Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2015-01-09 23:19:12 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2015-01-10 02:04:43 +0300
commit79d8617424daeda01c01924c7067e1be71516ecb (patch)
tree488fbc977b3615e93d99882cd2d177e333fa36bc
parent86159776241aad94301e152d44de59ff382fd3a9 (diff)
Transfer data: add modifier.
Not much to add, modifier uses same code as operator basically, only key difference is that modifier will never create data layers itself, you have to use dedicated operator for that.
-rw-r--r--release/datafiles/blender_icons.svg502
-rw-r--r--release/datafiles/blender_icons16/icon16_mod_data_transfer.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_mod_data_transfer.datbin0 -> 4120 bytes
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py115
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c6
-rw-r--r--source/blender/editors/include/UI_icons.h2
-rw-r--r--source/blender/editors/object/object_data_transfer.c31
-rw-r--r--source/blender/editors/object/object_intern.h11
-rw-r--r--source/blender/editors/object/object_modifier.c10
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h43
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c511
-rw-r--r--source/blender/modifiers/CMakeLists.txt1
-rw-r--r--source/blender/modifiers/MOD_modifiertypes.h1
-rw-r--r--source/blender/modifiers/intern/MOD_datatransfer.c221
-rw-r--r--source/blender/modifiers/intern/MOD_util.c1
17 files changed, 1442 insertions, 16 deletions
diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg
index ed5e84778f9..8fa93b412a6 100644
--- a/release/datafiles/blender_icons.svg
+++ b/release/datafiles/blender_icons.svg
@@ -27,6 +27,137 @@
<defs
id="defs4">
<linearGradient
+ inkscape:collect="always"
+ id="linearGradient20043">
+ <stop
+ style="stop-color:#f6e18c;stop-opacity:1;"
+ offset="0"
+ id="stop20045" />
+ <stop
+ style="stop-color:#f6e18c;stop-opacity:0;"
+ offset="1"
+ id="stop20047" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient20020">
+ <stop
+ style="stop-color:#f6e18c;stop-opacity:1;"
+ offset="0"
+ id="stop20022" />
+ <stop
+ style="stop-color:#f6e18c;stop-opacity:0;"
+ offset="1"
+ id="stop20024" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18512">
+ <stop
+ id="stop18514"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop18516"
+ offset="1"
+ style="stop-color:#f20000;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18495"
+ inkscape:collect="always">
+ <stop
+ id="stop18497"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop18499"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18479"
+ inkscape:collect="always">
+ <stop
+ id="stop18481"
+ offset="0"
+ style="stop-color:#8d8d8d;stop-opacity:1;" />
+ <stop
+ id="stop18483"
+ offset="1"
+ style="stop-color:#8d8d8d;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient18414">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop18416" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop18418" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18370"
+ inkscape:collect="always">
+ <stop
+ id="stop18372"
+ offset="0"
+ style="stop-color:#afafaf;stop-opacity:1;" />
+ <stop
+ id="stop18374"
+ offset="1"
+ style="stop-color:#afafaf;stop-opacity:0;" />
+ </linearGradient>
+ <marker
+ inkscape:stockid="Arrow1Lstart"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Lstart"
+ style="overflow:visible">
+ <path
+ id="path17576"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
+ transform="scale(0.8) translate(12.5,0)" />
+ </marker>
+ <linearGradient
+ id="linearGradient17566"
+ inkscape:collect="always">
+ <stop
+ id="stop17568"
+ offset="0"
+ style="stop-color:#cad8ee;stop-opacity:1;" />
+ <stop
+ id="stop17570"
+ offset="1"
+ style="stop-color:#cad8ee;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17560">
+ <stop
+ id="stop17562"
+ offset="0"
+ style="stop-color:#ffe991;stop-opacity:1;" />
+ <stop
+ id="stop17564"
+ offset="1"
+ style="stop-color:#ffe991;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17542"
+ inkscape:collect="always">
+ <stop
+ id="stop17544"
+ offset="0"
+ style="stop-color:#799ed3;stop-opacity:1;" />
+ <stop
+ id="stop17546"
+ offset="1"
+ style="stop-color:#799ed3;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
id="linearGradient17265">
<stop
style="stop-color:#ffb769;stop-opacity:1;"
@@ -29053,6 +29184,288 @@
id="linearGradient17872"
xlink:href="#linearGradient319-36-40-2-4"
inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient23974-41">
+ <stop
+ id="stop23976-66"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-15"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-68">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-221" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-90" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-84">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-86" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-4">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-3" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-8">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-0" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-648" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16605">
+ <stop
+ id="stop16607"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop16609"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18105-1">
+ <stop
+ id="stop18107-7"
+ offset="0"
+ style="stop-color:#162d50;stop-opacity:1" />
+ <stop
+ id="stop18109-8"
+ offset="1"
+ style="stop-color:#1e3e70;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17542"
+ id="linearGradient18237"
+ gradientUnits="userSpaceOnUse"
+ x1="231.35262"
+ y1="465.73871"
+ x2="246.08743"
+ y2="465.14655"
+ gradientTransform="matrix(0.86988738,-0.49325039,0.49325039,0.86988738,0,0.02266763)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17566"
+ id="linearGradient18239"
+ gradientUnits="userSpaceOnUse"
+ x1="430.78629"
+ y1="290.24094"
+ x2="440.83713"
+ y2="286.97058" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-41"
+ id="linearGradient18243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.53857,-4.802156)"
+ x1="107.39532"
+ y1="58.065113"
+ x2="127.70434"
+ y2="58.065113" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-68"
+ id="linearGradient18245"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1000194,0,0,1.0998287,110.29549,-8.6726854)"
+ x1="30.389694"
+ y1="95.008034"
+ x2="65.52562"
+ y2="93.69249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-84"
+ id="linearGradient18247"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="483.00034"
+ y1="163"
+ x2="476.68781"
+ y2="162.85956" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-4"
+ id="linearGradient18249"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(342.00029,383.00889)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="134.30893"
+ y2="-218.00888" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-8"
+ id="linearGradient18251"
+ gradientUnits="userSpaceOnUse"
+ x1="475.00034"
+ y1="155"
+ x2="469.75034"
+ y2="155" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-41"
+ id="linearGradient18253"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(14.285126,-0.22103087)"
+ x1="442.81525"
+ y1="290.49384"
+ x2="436.5"
+ y2="290.5249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18105-1"
+ id="linearGradient18255"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.285126,-0.22097087)"
+ x1="445.99902"
+ y1="288.5"
+ x2="407.3793"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17560-4"
+ id="linearGradient18241-0"
+ gradientUnits="userSpaceOnUse"
+ x1="327.77432"
+ y1="251.04707"
+ x2="335.80118"
+ y2="247.0696" />
+ <linearGradient
+ id="linearGradient17560-4">
+ <stop
+ id="stop17562-3"
+ offset="0"
+ style="stop-color:#ffe991;stop-opacity:1;" />
+ <stop
+ id="stop17564-1"
+ offset="1"
+ style="stop-color:#ffe991;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18370"
+ id="linearGradient18368"
+ x1="432.83759"
+ y1="289.15814"
+ x2="441.44028"
+ y2="283.54819"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ y2="245.78732"
+ x2="335.8941"
+ y1="251.04707"
+ x1="327.77432"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient18313-9"
+ xlink:href="#linearGradient17560-4-9"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient17560-4-9">
+ <stop
+ id="stop17562-3-7"
+ offset="0"
+ style="stop-color:#ffe991;stop-opacity:1;" />
+ <stop
+ id="stop17564-1-4"
+ offset="1"
+ style="stop-color:#ffe991;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18414"
+ id="linearGradient18420"
+ x1="333.8428"
+ y1="253.4225"
+ x2="327.0369"
+ y2="243.12526"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18414-5"
+ id="linearGradient18420-1"
+ x1="333.8428"
+ y1="253.4225"
+ x2="327.0369"
+ y2="243.12526"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient18414-5">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop18416-8" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop18418-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18479"
+ id="linearGradient18476"
+ x1="427.86765"
+ y1="284.7648"
+ x2="431.31277"
+ y2="278.92789"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.46468729,2.0195829)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18495"
+ id="linearGradient18493"
+ x1="323.68958"
+ y1="248.71513"
+ x2="335.125"
+ y2="245.5"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20020"
+ id="linearGradient20026"
+ x1="331.22147"
+ y1="249.03816"
+ x2="336.11465"
+ y2="244.64084"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20043"
+ id="linearGradient20049"
+ x1="148.21956"
+ y1="506.48343"
+ x2="155.67555"
+ y2="506.45177"
+ gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
@@ -29064,11 +29477,11 @@
objecttolerance="10000"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="8"
- inkscape:cx="475.21328"
- inkscape:cy="281.82297"
+ inkscape:zoom="16"
+ inkscape:cx="320.24884"
+ inkscape:cy="387.11918"
inkscape:document-units="px"
- inkscape:current-layer="layer1"
+ inkscape:current-layer="g18198-9"
showgrid="true"
inkscape:window-width="1920"
inkscape:window-height="980"
@@ -89624,6 +90037,87 @@
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
inkscape:connector-curvature="0" />
+ <g
+ id="g18205"
+ transform="matrix(1.0087429,0,0,0.97482999,-2.7977369,3.5855352)">
+ <rect
+ ry="1.5303751"
+ rx="1.479782"
+ y="243.54448"
+ x="320"
+ height="16.413118"
+ width="15.861326"
+ id="rect18203"
+ style="fill:none;stroke:none" />
+ <g
+ id="g18198"
+ transform="translate(-105.12972,-37.013919)">
+ <path
+ style="fill:url(#linearGradient18237);fill-opacity:1;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 425.50477,292.38372 15.04989,-10.90405 -0.0101,6.77582 -9.51239,8.38266 z"
+ id="rect16727"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:none;stroke:url(#linearGradient18239);stroke-width:0.94270116;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 439.79125,287.61126 -8.80214,7.81233 -3.87477,-2.96997 12.64026,-9.16307"
+ id="rect16727-8"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ transform="matrix(0.74622014,-0.66569926,0.64008794,0.76830165,0,0)"
+ style="fill:url(#linearGradient20049);fill-opacity:1;stroke:none"
+ d="m 155.67553,506.23194 -0.63498,0.7272 c 0,0 -7.96167,0.0866 -11.40538,0.0765 -1.63408,-0.005 -1.64706,-1.90745 -0.31608,-1.84971 3.85215,0.16711 12.35647,1.04592 12.35647,1.04592 z"
+ id="rect20031"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsscc" />
+ </g>
+ <g
+ style="display:inline;enable-background:new;fill-opacity:1;fill:url(#linearGradient18368)"
+ id="g18198-9"
+ transform="translate(-105.1466,-36.99669)">
+ <path
+ style="fill:url(#linearGradient18420);fill-opacity:1;stroke:none"
+ d="m 321.20705,242.0789 c 2.69584,0.64081 4.09152,0.77931 6.28874,0.55186 0.26517,2.2318 0.84364,4.80456 2.06664,6.25861 -2.05408,-0.68406 -3.57488,-1.60349 -4.80908,-2.47909 -1.36678,-1.11314 -2.52984,-2.47523 -3.5463,-4.33138 z"
+ id="path18412"
+ inkscape:connector-curvature="0"
+ transform="matrix(0.99133288,0,0,1.0258199,107.92009,33.318577)"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:none;stroke:#1a1a1a;stroke-width:0.70590025;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.49803922;stroke-dasharray:none"
+ d="m 433.63404,285.72236 c 0.73437,0.0551 1.7644,-0.46216 6.92062,-4.29741 0,3.16617 -0.0101,4.19989 -0.0101,6.77582 -0.44137,0.51649 -6.49867,5.40547 -7.65364,-6.3635 -3.13764,0.28442 -4.5477,0.084 -7.20028,-0.77628 1.34066,3.00122 2.84213,4.52716 4.53015,5.73115 2.02689,1.39249 4.23484,2.31245 6.40718,2.76405"
+ id="rect16727-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:none;stroke:url(#linearGradient18476);stroke-width:0.70590028;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.49803922000000000;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 429.7959,286.22706 c -0.643,-0.69986 -1.96564,-2.36658 -2.68852,-3.95331 2.06071,0.57118 3.81157,0.50289 5.11146,0.38221 0.26288,2.28943 0.88014,4.42993 1.66538,5.3435"
+ id="path18412-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:url(#linearGradient18493);fill-opacity:1;stroke:none"
+ d="m 335.20234,242.58443 c 0,0.84375 -0.005,3.9971 -0.005,5.75999 -2.37119,1.76035 -4.7166,1.79719 -6.03803,-1.54307 1.55369,-1.16687 6.02002,-4.2052 6.02002,-4.2052 z"
+ id="path18485"
+ inkscape:connector-curvature="0"
+ transform="matrix(0.99133288,0,0,1.0258199,107.92009,33.318577)"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:url(#linearGradient20026);fill-opacity:1;stroke:none"
+ d="m 335.23044,245.54814 c 0,0 0.0166,0.39923 0.0166,1.01647 -0.82312,0.76235 -3.0673,2.74764 -4.18325,2.66033 -0.29848,-0.14345 -0.39809,-0.20898 -0.62335,-0.46278 1.10175,-0.45288 2.17708,-1.29548 4.79,-3.21402 z"
+ id="path20010"
+ inkscape:connector-curvature="0"
+ transform="matrix(0.99133288,0,0,1.0258199,107.90321,33.335806)"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#ffe991;fill-opacity:1;stroke:none"
+ d="m 329.55657,248.86283 c -1.41211,-0.48222 -3.92872,-1.40598 -4.73299,-4.22946 -0.39317,-1.38024 1.7085,-1.41702 1.92756,-0.24049 0.45159,2.42548 1.89945,3.56397 2.80543,4.46995 z"
+ id="path18570"
+ inkscape:connector-curvature="0"
+ transform="matrix(0.99133288,0,0,1.0258199,107.90321,33.335806)"
+ sodipodi:nodetypes="cssc" />
+ </g>
+ </g>
</g>
<g
inkscape:groupmode="layer"
diff --git a/release/datafiles/blender_icons16/icon16_mod_data_transfer.dat b/release/datafiles/blender_icons16/icon16_mod_data_transfer.dat
new file mode 100644
index 00000000000..53b5d3eae1a
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_mod_data_transfer.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_mod_data_transfer.dat b/release/datafiles/blender_icons32/icon32_mod_data_transfer.dat
new file mode 100644
index 00000000000..a405606a0e5
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_mod_data_transfer.dat
Binary files differ
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 7a969963911..e13d007a6d6 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1225,6 +1225,121 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "material_offset", text="Material Offset")
+ def DATA_TRANSFER(self, layout, ob, md):
+ row = layout.row(align=True)
+ row.prop(md, "object")
+ sub = row.row(align=True)
+ sub.active = bool(md.object)
+ sub.prop(md, "use_object_transform", text="", icon='GROUP')
+
+ layout.separator()
+
+ split = layout.split(0.333)
+ split.prop(md, "use_vert_data")
+ use_vert = md.use_vert_data
+ row = split.row()
+ row.active = use_vert
+ row.prop(md, "vert_mapping", text="")
+ if use_vert:
+ col = layout.column(align=True)
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_verts_vgroup")
+ row = split.row(align=True)
+ row.prop(md, "layers_vgroup_select_src", text="")
+ row.label(icon='RIGHTARROW_THIN')
+ row.prop(md, "layers_vgroup_select_dst", text="")
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_verts")
+
+ layout.separator()
+
+ split = layout.split(0.333)
+ split.prop(md, "use_edge_data")
+ use_edge = md.use_edge_data
+ row = split.row()
+ row.active = use_edge
+ row.prop(md, "edge_mapping", text="")
+ if use_edge:
+ col = layout.column(align=True)
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_edges")
+
+ layout.separator()
+
+ split = layout.split(0.333)
+ split.prop(md, "use_loop_data")
+ use_loop = md.use_loop_data
+ row = split.row()
+ row.active = use_loop
+ row.prop(md, "loop_mapping", text="")
+ if use_loop:
+ col = layout.column(align=True)
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_loops")
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_loops_vcol")
+ row = split.row(align=True)
+ row.prop(md, "layers_vcol_select_src", text="")
+ row.label(icon='RIGHTARROW')
+ row.prop(md, "layers_vcol_select_dst", text="")
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_loops_uv")
+ row = split.row(align=True)
+ row.prop(md, "layers_uv_select_src", text="")
+ row.label(icon='RIGHTARROW')
+ row.prop(md, "layers_uv_select_dst", text="")
+ col.prop(md, "islands_precision")
+
+ layout.separator()
+
+ split = layout.split(0.333)
+ split.prop(md, "use_poly_data")
+ use_poly = md.use_poly_data
+ row = split.row()
+ row.active = use_poly
+ row.prop(md, "poly_mapping", text="")
+ if use_poly:
+ col = layout.column(align=True)
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_polys")
+
+ layout.separator()
+
+ split = layout.split()
+ col = split.column()
+ row = col.row(align=True)
+ sub = row.row(align=True)
+ sub.active = md.use_max_distance
+ sub.prop(md, "max_distance")
+ row.prop(md, "use_max_distance", text="", icon='STYLUS_PRESSURE')
+
+ col = split.column()
+ col.prop(md, "ray_radius")
+
+ layout.separator()
+
+ split = layout.split()
+ col = split.column()
+ col.prop(md, "mix_mode")
+ col.prop(md, "mix_factor")
+
+ col = split.column()
+ row = col.row()
+ row.active = bool(md.object)
+ row.operator("object.datalayout_transfer", text="Generate Data Layers")
+ row = col.row(align=True)
+ row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+ sub = row.row(align=True)
+ sub.active = bool(md.vertex_group)
+ sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
+
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 268c911fc54..abc544ea70e 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1449,8 +1449,10 @@ static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *UNUSED(ob))
*/
static void dm_ensure_display_normals(DerivedMesh *dm)
{
- /* this is for final output only, up until now this layer should be missing */
- BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
+ /* Note: dm *may* have a poly CD_NORMAL layer (generated by a modifier needing poly normals e.g.).
+ * We do not use it here, though. And it should be tagged as temp!
+ */
+ /* BLI_assert((CustomData_has_layer(&dm->polyData, CD_NORMAL) == false)); */
if ((dm->type == DM_TYPE_CDDM) &&
((dm->dirty & DM_DIRTY_NORMALS) || CustomData_has_layer(&dm->faceData, CD_NORMAL) == false))
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index 618fa44349e..2313ccfc69b 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -589,8 +589,8 @@ DEF_ICON(MOD_WARP)
DEF_ICON(MOD_SKIN)
DEF_ICON(MOD_TRIANGULATE)
DEF_ICON(MOD_WIREFRAME)
+DEF_ICON(MOD_DATA_TRANSFER)
#ifndef DEF_ICON_BLANK_SKIP
- DEF_ICON(BLANK167)
DEF_ICON(BLANK168)
DEF_ICON(BLANK169)
DEF_ICON(BLANK170)
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index 1d994746ba6..8dfd31c92bb 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -535,15 +535,33 @@ void OBJECT_OT_data_transfer(wmOperatorType *ot)
static int datalayout_transfer_poll(bContext *C)
{
- return (data_transfer_poll(C));
+ return (edit_modifier_poll_generic(C, &RNA_DataTransferModifier, (1 << OB_MESH)) || data_transfer_poll(C));
}
static int datalayout_transfer_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *ob_act = ED_object_active_context(C);
+ DataTransferModifierData *dtmd;
- {
+ dtmd = (DataTransferModifierData *)edit_modifier_property_get(op, ob_act, eModifierType_DataTransfer);
+
+ /* If we have a modifier, we transfer data layout from this modifier's source object to active one.
+ * Else, we transfer data layout from active object to all selected ones. */
+ if (dtmd) {
+ Object *ob_src = dtmd->ob_source;
+ Object *ob_dst = ob_act;
+
+ const bool use_delete = false; /* Never when used from modifier, for now. */
+
+ if (!ob_src) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BKE_object_data_transfer_layout(scene, ob_src, ob_dst, dtmd->data_types, use_delete,
+ dtmd->layers_select_src, dtmd->layers_select_dst);
+ }
+ else {
Object *ob_src = ob_act;
ListBase ctx_objects;
@@ -581,7 +599,12 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op)
static int datalayout_transfer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- return WM_menu_invoke(C, op, event);
+ if (edit_modifier_invoke_properties(C, op)) {
+ return datalayout_transfer_exec(C, op);
+ }
+ else {
+ return WM_menu_invoke(C, op, event);
+ }
}
void OBJECT_OT_datalayout_transfer(wmOperatorType *ot)
@@ -602,7 +625,7 @@ void OBJECT_OT_datalayout_transfer(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* Properties.*/
- /* edit_modifier_properties(ot); */
+ edit_modifier_properties(ot);
/* Data type to transfer. */
ot->prop = RNA_def_enum(ot->srna, "data_type", DT_layer_items, 0, "Data Type", "Which data to transfer");
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index bcf77d819fe..207afdf1028 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -37,6 +37,11 @@ struct Lattice;
struct Curve;
struct Object;
struct Mesh;
+struct bContext;
+struct StructRNA;
+struct wmOperator;
+
+struct ModifierData;
struct HookModifierData;
/* add hook menu */
@@ -155,6 +160,12 @@ void GROUP_OT_objects_add_active(struct wmOperatorType *ot);
void GROUP_OT_objects_remove_active(struct wmOperatorType *ot);
/* object_modifier.c */
+int edit_modifier_poll_generic(struct bContext *C, struct StructRNA *rna_type, int obtype_flag);
+int edit_modifier_poll(struct bContext *C);
+void edit_modifier_properties(struct wmOperatorType *ot);
+int edit_modifier_invoke_properties(struct bContext *C, struct wmOperator *op);
+struct ModifierData *edit_modifier_property_get(struct wmOperator *op, struct Object *ob, int type);
+
void OBJECT_OT_modifier_add(struct wmOperatorType *ot);
void OBJECT_OT_modifier_remove(struct wmOperatorType *ot);
void OBJECT_OT_modifier_move_up(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 97556365466..5a479af83b5 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -808,7 +808,7 @@ void OBJECT_OT_modifier_add(wmOperatorType *ot)
/************************ generic functions for operators using mod names and data context *********************/
-static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
+int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
{
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type);
Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C);
@@ -820,17 +820,17 @@ static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obty
return 1;
}
-static int edit_modifier_poll(bContext *C)
+int edit_modifier_poll(bContext *C)
{
return edit_modifier_poll_generic(C, &RNA_Modifier, 0);
}
-static void edit_modifier_properties(wmOperatorType *ot)
+void edit_modifier_properties(wmOperatorType *ot)
{
RNA_def_string(ot->srna, "modifier", NULL, MAX_NAME, "Modifier", "Name of the modifier to edit");
}
-static int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
+int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
{
ModifierData *md;
@@ -849,7 +849,7 @@ static int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
return false;
}
-static ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
+ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
{
char modifier_name[MAX_NAME];
ModifierData *md;
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 3df6bd51f37..a963f422cb7 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -1018,6 +1018,8 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
UI_icon_draw(x, y, ICON_MOD_WIREFRAME); break;
case eModifierType_LaplacianDeform:
UI_icon_draw(x, y, ICON_MOD_MESHDEFORM); break; /* XXX, needs own icon */
+ case eModifierType_DataTransfer:
+ UI_icon_draw(x, y, ICON_MOD_DATA_TRANSFER); break;
/* Default */
case eModifierType_None:
case eModifierType_ShapeKey:
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 47782bb3ae1..b1e9fd254e1 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -82,6 +82,7 @@ typedef enum ModifierType {
eModifierType_MeshCache = 46,
eModifierType_LaplacianDeform = 47,
eModifierType_Wireframe = 48,
+ eModifierType_DataTransfer = 49,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -1367,5 +1368,47 @@ enum {
};
+typedef struct DataTransferModifierData {
+ ModifierData modifier;
+
+ struct Object *ob_source;
+
+ int data_types; /* See DT_TYPE_ enum in ED_object.h */
+
+ /* See MREMAP_MODE_ enum in BKE_mesh_mapping.h */
+ int vmap_mode;
+ int emap_mode;
+ int lmap_mode;
+ int pmap_mode;
+
+ float map_max_distance;
+ float map_ray_radius;
+ float islands_precision;
+
+ int pad_i1;
+
+ int layers_select_src[4]; /* DT_MULTILAYER_INDEX_MAX; See DT_FROMLAYERS_ enum in ED_object.h */
+ int layers_select_dst[4]; /* DT_MULTILAYER_INDEX_MAX; See DT_TOLAYERS_ enum in ED_object.h */
+
+ int mix_mode; /* See CDT_MIX_ enum in BKE_customdata.h */
+ float mix_factor;
+ char defgrp_name[64]; /* MAX_VGROUP_NAME */
+
+ int flags;
+} DataTransferModifierData;
+
+/* DataTransferModifierData.flags */
+enum {
+ MOD_DATATRANSFER_OBSRC_TRANSFORM = 1 << 0,
+ MOD_DATATRANSFER_MAP_MAXDIST = 1 << 1,
+ MOD_DATATRANSFER_INVERT_VGROUP = 1 << 2,
+
+ /* Only for UI really. */
+ MOD_DATATRANSFER_USE_VERT = 1 << 28,
+ MOD_DATATRANSFER_USE_EDGE = 1 << 29,
+ MOD_DATATRANSFER_USE_LOOP = 1 << 30,
+ MOD_DATATRANSFER_USE_POLY = 1 << 31,
+};
+
#endif /* __DNA_MODIFIER_TYPES_H__ */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 0a1eb102d8c..6167164a7ac 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -199,6 +199,7 @@ extern StructRNA RNA_CurveMapping;
extern StructRNA RNA_CurveModifier;
extern StructRNA RNA_CurvePoint;
extern StructRNA RNA_DampedTrackConstraint;
+extern StructRNA RNA_DataTransferModifier;
extern StructRNA RNA_DecimateModifier;
extern StructRNA RNA_DelaySensor;
extern StructRNA RNA_DisplaceModifier;
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 1cd646b1914..9780c45867e 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -51,6 +51,7 @@
#include "BKE_multires.h"
#include "BKE_smoke.h" /* For smokeModifier_free & smokeModifier_createType */
+#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -68,6 +69,7 @@ EnumPropertyItem modifier_type_items[] = {
{eModifierType_WeightVGMix, "VERTEX_WEIGHT_MIX", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Mix", ""},
{eModifierType_WeightVGProximity, "VERTEX_WEIGHT_PROXIMITY", ICON_MOD_VERTEX_WEIGHT,
"Vertex Weight Proximity", ""},
+ {eModifierType_DataTransfer, "DATA_TRANSFER", ICON_MOD_DATA_TRANSFER, "Data Transfer", ""},
{0, "", 0, N_("Generate"), ""},
{eModifierType_Array, "ARRAY", ICON_MOD_ARRAY, "Array", ""},
{eModifierType_Bevel, "BEVEL", ICON_MOD_BEVEL, "Bevel", ""},
@@ -353,6 +355,8 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
return &RNA_LaplacianDeformModifier;
case eModifierType_Wireframe:
return &RNA_WireframeModifier;
+ case eModifierType_DataTransfer:
+ return &RNA_DataTransferModifier;
/* Default */
case eModifierType_None:
case eModifierType_ShapeKey:
@@ -418,6 +422,7 @@ RNA_MOD_VGROUP_NAME_SET(Armature, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Bevel, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Cast, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Curve, name);
+RNA_MOD_VGROUP_NAME_SET(DataTransfer, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Decimate, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Displace, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Hook, name);
@@ -508,6 +513,7 @@ RNA_MOD_OBJECT_SET(Array, curve_ob, OB_CURVE);
RNA_MOD_OBJECT_SET(Boolean, object, OB_MESH);
RNA_MOD_OBJECT_SET(Cast, object, OB_EMPTY);
RNA_MOD_OBJECT_SET(Curve, object, OB_CURVE);
+RNA_MOD_OBJECT_SET(DataTransfer, ob_source, OB_MESH);
RNA_MOD_OBJECT_SET(Lattice, object, OB_LATTICE);
RNA_MOD_OBJECT_SET(Mask, ob_arm, OB_ARMATURE);
RNA_MOD_OBJECT_SET(MeshDeform, object, OB_MESH);
@@ -747,6 +753,265 @@ static void rna_ArrayModifier_dependency_update(Main *bmain, Scene *scene, Point
}
}
+
+static void rna_DataTransferModifier_use_data_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)ptr->data;
+
+ if (!(dtmd->flags & MOD_DATATRANSFER_USE_VERT)) {
+ dtmd->data_types &= ~DT_TYPE_VERT_ALL;
+ }
+ if (!(dtmd->flags & MOD_DATATRANSFER_USE_EDGE)) {
+ dtmd->data_types &= ~DT_TYPE_EDGE_ALL;
+ }
+ if (!(dtmd->flags & MOD_DATATRANSFER_USE_LOOP)) {
+ dtmd->data_types &= ~DT_TYPE_LOOP_ALL;
+ }
+ if (!(dtmd->flags & MOD_DATATRANSFER_USE_POLY)) {
+ dtmd->data_types &= ~DT_TYPE_POLY_ALL;
+ }
+
+ rna_Modifier_update(bmain, scene, ptr);
+}
+
+static void rna_DataTransferModifier_data_types_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)ptr->data;
+ const int item_types = BKE_object_data_transfer_get_dttypes_item_types(dtmd->data_types);
+
+ if (item_types & ME_VERT) {
+ dtmd->flags |= MOD_DATATRANSFER_USE_VERT;
+ }
+ if (item_types & ME_EDGE) {
+ dtmd->flags |= MOD_DATATRANSFER_USE_EDGE;
+ }
+ if (item_types & ME_LOOP) {
+ dtmd->flags |= MOD_DATATRANSFER_USE_LOOP;
+ }
+ if (item_types & ME_POLY) {
+ dtmd->flags |= MOD_DATATRANSFER_USE_POLY;
+ }
+
+ rna_Modifier_update(bmain, scene, ptr);
+}
+
+static EnumPropertyItem *rna_DataTransferModifier_layers_select_src_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)ptr->data;
+ EnumPropertyItem *item = NULL, tmp_item = {0};
+ int totitem = 0;
+
+ if (!C) { /* needed for docs and i18n tools */
+ return DT_layers_select_src_items;
+ }
+
+ /* No active here! */
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_ALL_SRC);
+
+ if (STREQ(RNA_property_identifier(prop), "layers_vgroup_select_src")) {
+ Object *ob_src = dtmd->ob_source;
+
+#if 0 /* XXX Don't think we want this in modifier version... */
+ if (BKE_object_pose_armature_get(ob_src)) {
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_SELECT);
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_DEFORM);
+ }
+#endif
+
+ if (ob_src) {
+ bDeformGroup *dg;
+ int i;
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0, dg = ob_src->defbase.first; dg; i++, dg = dg->next) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = dg->name;
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+ else if (STREQ(RNA_property_identifier(prop), "layers_shapekey_select_src")) {
+ /* TODO */
+ }
+ else if (STREQ(RNA_property_identifier(prop), "layers_uv_select_src")) {
+ Object *ob_src = dtmd->ob_source;
+
+ if (ob_src) {
+ DerivedMesh *dm_src;
+ CustomData *pdata;
+ int num_data, i;
+
+ /* XXX Is this OK? */
+ dm_src = mesh_get_derived_final(dtmd->modifier.scene, ob_src, CD_MASK_BAREMESH | CD_MTEXPOLY);
+ pdata = dm_src->getPolyDataLayout(dm_src);
+ num_data = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0; i < num_data; i++) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(pdata, CD_MTEXPOLY, i);
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+ else if (STREQ(RNA_property_identifier(prop), "layers_vcol_select_src")) {
+ Object *ob_src = dtmd->ob_source;
+
+ if (ob_src) {
+ DerivedMesh *dm_src;
+ CustomData *ldata;
+ int num_data, i;
+
+ /* XXX Is this OK? */
+ dm_src = mesh_get_derived_final(dtmd->modifier.scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPCOL);
+ ldata = dm_src->getLoopDataLayout(dm_src);
+ num_data = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0; i < num_data; i++) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPCOL, i);
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+static EnumPropertyItem *rna_DataTransferModifier_layers_select_dst_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)ptr->data;
+ EnumPropertyItem *item = NULL, tmp_item = {0};
+ int totitem = 0;
+
+ if (!C) { /* needed for docs and i18n tools */
+ return DT_layers_select_dst_items;
+ }
+
+ /* No active here! */
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_dst_items, DT_LAYERS_NAME_DST);
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_dst_items, DT_LAYERS_INDEX_DST);
+
+ if (STREQ(RNA_property_identifier(prop), "layers_vgroup_select_dst")) {
+ /* Only list destination layers if we have a single source! */
+ if (dtmd->layers_select_src[DT_MULTILAYER_INDEX_MDEFORMVERT] >= 0) {
+ Object *ob_dst = CTX_data_active_object(C); /* XXX Is this OK? */
+
+ if (ob_dst) {
+ bDeformGroup *dg;
+ int i;
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0, dg = ob_dst->defbase.first; dg; i++, dg = dg->next) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = dg->name;
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+ }
+ else if (STREQ(RNA_property_identifier(prop), "layers_shapekey_select_dst")) {
+ /* TODO */
+ }
+ else if (STREQ(RNA_property_identifier(prop), "layers_uv_select_dst")) {
+ /* Only list destination layers if we have a single source! */
+ if (dtmd->layers_select_src[DT_MULTILAYER_INDEX_UV] >= 0) {
+ Object *ob_dst = CTX_data_active_object(C); /* XXX Is this OK? */
+
+ if (ob_dst && ob_dst->data) {
+ Mesh *me_dst;
+ CustomData *pdata;
+ int num_data, i;
+
+ me_dst = ob_dst->data;
+ pdata = &me_dst->pdata;
+ num_data = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0; i < num_data; i++) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(pdata, CD_MTEXPOLY, i);
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+ }
+ else if (STREQ(RNA_property_identifier(prop), "layers_vcol_select_dst")) {
+ /* Only list destination layers if we have a single source! */
+ if (dtmd->layers_select_src[DT_MULTILAYER_INDEX_VCOL] >= 0) {
+ Object *ob_dst = CTX_data_active_object(C); /* XXX Is this OK? */
+
+ if (ob_dst && ob_dst->data) {
+ Mesh *me_dst;
+ CustomData *ldata;
+ int num_data, i;
+
+ me_dst = ob_dst->data;
+ ldata = &me_dst->ldata;
+ num_data = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0; i < num_data; i++) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPCOL, i);
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+ }
+
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+static EnumPropertyItem *rna_DataTransferModifier_mix_mode_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)ptr->data;
+ EnumPropertyItem *item = NULL;
+ int totitem = 0;
+
+ bool support_advanced_mixing, support_threshold;
+
+ if (!C) { /* needed for docs and i18n tools */
+ return DT_mix_mode_items;
+ }
+
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_TRANSFER);
+
+ BKE_object_data_transfer_get_dttypes_capacity(dtmd->data_types, &support_advanced_mixing, &support_threshold);
+
+ if (support_advanced_mixing) {
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_REPLACE_ABOVE_THRESHOLD);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_REPLACE_BELOW_THRESHOLD);
+ }
+
+ if (support_advanced_mixing) {
+ RNA_enum_item_add_separator(&item, &totitem);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_MIX);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_ADD);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_SUB);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_MUL);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
#else
static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const char type[])
@@ -3807,6 +4072,251 @@ static void rna_def_modifier_wireframe(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
+static void rna_def_modifier_datatransfer(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem DT_layer_vert_items[] = {
+#if 0 /* XXX When SkinModifier is enabled, it seems to erase its own CD_MVERT_SKIN layer from final DM :( */
+ {DT_TYPE_SKIN, "SKIN", 0, "Skin Weight", "Transfer skin weights"},
+#endif
+ {DT_TYPE_BWEIGHT_VERT, "BEVEL_WEIGHT_VERT", 0, "Bevel Weight", "Transfer bevel weights"},
+ {0, NULL, 0, NULL, NULL}
+ };
+ static EnumPropertyItem DT_layer_vert_vgroup_items[] = {
+ {DT_TYPE_MDEFORMVERT, "VGROUP_WEIGHTS", 0, "Vertex Group(s)", "Transfer active or all vertex groups"},
+ {0, NULL, 0, NULL, NULL}
+ };
+#if 0 /* XXX For now, would like to finish/merge work from 2014 gsoc first. */
+ static EnumPropertyItem DT_layer_vert_shapekey_items[] = {
+ {DT_TYPE_SHAPEKEY, "SHAPEKEYS", 0, "Shapekey(s)", "Transfer active or all shape keys"},
+ {0, NULL, 0, NULL, NULL}
+ };
+#endif
+
+ static EnumPropertyItem DT_layer_edge_items[] = {
+ {DT_TYPE_SHARP_EDGE, "SHARP_EDGE", 0, "Sharp", "Transfer sharp mark"},
+ {DT_TYPE_SEAM, "SEAM", 0, "UV Seam", "Transfer UV seam mark"},
+ {DT_TYPE_CREASE, "CREASE", 0, "Subsurf Crease", "Transfer crease values"},
+ {DT_TYPE_BWEIGHT_EDGE, "BEVEL_WEIGHT_EDGE", 0, "Bevel Weight", "Transfer bevel weights"},
+ {DT_TYPE_FREESTYLE_EDGE, "FREESTYLE_EDGE", 0, "Freestyle Mark", "Transfer Freestyle edge mark"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem DT_layer_loop_items[] = {
+ {0, NULL, 0, NULL, NULL}
+ };
+ static EnumPropertyItem DT_layer_loop_vcol_items[] = {
+ {DT_TYPE_VCOL, "VCOL", 0, "VCol", "Vertex (face corners) colors"},
+ {0, NULL, 0, NULL, NULL}
+ };
+ static EnumPropertyItem DT_layer_loop_uv_items[] = {
+ {DT_TYPE_UV, "UV", 0, "UVs", "Transfer UV layers"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem DT_layer_poly_items[] = {
+ {DT_TYPE_SHARP_FACE, "SMOOTH", 0, "Smooth", "Transfer flat/smooth mark"},
+ {DT_TYPE_FREESTYLE_FACE, "FREESTYLE_FACE", 0, "Freestyle Mark", "Transfer Freestyle face mark"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ srna = RNA_def_struct(brna, "DataTransferModifier", "Modifier");
+ RNA_def_struct_ui_text(srna, "Data Transfer Modifier", "Modifier transferring some data from a source mesh");
+ RNA_def_struct_sdna(srna, "DataTransferModifierData");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_DATA_TRANSFER);
+
+ prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "ob_source");
+ RNA_def_property_ui_text(prop, "Source Object", "Object to transfer data from");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_DataTransferModifier_ob_source_set", NULL, "rna_Mesh_object_poll");
+ RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
+ prop = RNA_def_boolean(srna, "use_object_transform", true, "Object Transform",
+ "Evaluate source and destination meshes in their respective object spaces");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_OBSRC_TRANSFORM);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* Generic, UI-only data types toggles. */
+ prop = RNA_def_boolean(srna, "use_vert_data", false, "Vertex Data", "Enable vertex data transfer");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_USE_VERT);
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_use_data_update");
+
+ prop = RNA_def_boolean(srna, "use_edge_data", false, "Edge Data", "Enable edge data transfer");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_USE_EDGE);
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_use_data_update");
+
+ prop = RNA_def_boolean(srna, "use_loop_data", false, "Face Corner Data", "Enable face corner data transfer");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_USE_LOOP);
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_use_data_update");
+
+ prop = RNA_def_boolean(srna, "use_poly_data", false, "Face Data", "Enable face data transfer");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_USE_POLY);
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_use_data_update");
+
+ /* Actual data types selection. */
+ prop = RNA_def_enum(srna, "data_types_verts", DT_layer_vert_items, 0, "Vertex Data Types",
+ "Which vertex data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+ prop = RNA_def_enum(srna, "data_types_verts_vgroup", DT_layer_vert_vgroup_items, 0, "Vertex Data Types",
+ "Which vertex data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+
+ prop = RNA_def_enum(srna, "data_types_edges", DT_layer_edge_items, 0, "Edge Data Types",
+ "Which edge data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+
+ prop = RNA_def_enum(srna, "data_types_loops", DT_layer_loop_items, 0, "Face Corner Data Types",
+ "Which face corner data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+ prop = RNA_def_enum(srna, "data_types_loops_vcol", DT_layer_loop_vcol_items, 0, "Face Corner Data Types",
+ "Which face corner data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+ prop = RNA_def_enum(srna, "data_types_loops_uv", DT_layer_loop_uv_items, 0, "Face Corner Data Types",
+ "Which face corner data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+
+ prop = RNA_def_enum(srna, "data_types_polys", DT_layer_poly_items, 0, "Poly Data Types",
+ "Which poly data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+
+ /* Mapping methods. */
+ prop = RNA_def_enum(srna, "vert_mapping", DT_method_vertex_items, MREMAP_MODE_VERT_NEAREST, "Vertex Mapping",
+ "Method used to map source vertices to destination ones");
+ RNA_def_property_enum_sdna(prop, NULL, "vmap_mode");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_enum(srna, "edge_mapping", DT_method_edge_items, MREMAP_MODE_EDGE_NEAREST, "Edge Mapping",
+ "Method used to map source edges to destination ones");
+ RNA_def_property_enum_sdna(prop, NULL, "emap_mode");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_enum(srna, "loop_mapping", DT_method_loop_items, MREMAP_MODE_LOOP_NEAREST_POLYNOR,
+ "Face Corner Mapping", "Method used to map source faces' corners to destination ones");
+ RNA_def_property_enum_sdna(prop, NULL, "lmap_mode");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_enum(srna, "poly_mapping", DT_method_poly_items, MREMAP_MODE_POLY_NEAREST, "Face Mapping",
+ "Method used to map source faces to destination ones");
+ RNA_def_property_enum_sdna(prop, NULL, "pmap_mode");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* Mapping options and filtering. */
+ prop = RNA_def_boolean(srna, "use_max_distance", false, "Only Neighbor Geometry",
+ "Source elements must be closer than given distance from destination one");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_MAP_MAXDIST);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_float(srna, "max_distance", 1.0f, 0.0f, FLT_MAX, "Max Distance",
+ "Maximum allowed distance between source and destination element, for non-topology mappings",
+ 0.0f, 100.0f);
+ RNA_def_property_float_sdna(prop, NULL, "map_max_distance");
+ RNA_def_property_subtype(prop, PROP_DISTANCE);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_float(srna, "ray_radius", 0.0f, 0.0f, FLT_MAX, "Ray Radius",
+ "'Width' of rays (especially useful when raycasting against vertices or edges)", 0.0f, 10.0f);
+ RNA_def_property_float_sdna(prop, NULL, "map_ray_radius");
+ RNA_def_property_subtype(prop, PROP_DISTANCE);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_float(srna, "islands_precision", 0.0f, 0.0f, 1.0f, "Islands Handling Refinement",
+ "Factor controlling precision of islands handling "
+ "(typically, 0.1 should be enough, higher values can make things really slow)", 0.0f, 1.0f);
+ RNA_def_property_subtype(prop, PROP_DISTANCE);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* How to handle multi-layers types of data. */
+ prop = RNA_def_enum(srna, "layers_vgroup_select_src", DT_layers_select_src_items, DT_LAYERS_ALL_SRC,
+ "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_src[DT_MULTILAYER_INDEX_MDEFORMVERT]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_src_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+#if 0
+ prop = RNA_def_enum(srna, "layers_shapekey_select_src", DT_layers_select_src_items, DT_LAYERS_ALL_SRC,
+ "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_src[DT_MULTILAYER_INDEX_SHAPEKEY]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_src_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+#endif
+
+ prop = RNA_def_enum(srna, "layers_vcol_select_src", DT_layers_select_src_items, DT_LAYERS_ALL_SRC,
+ "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_src[DT_MULTILAYER_INDEX_VCOL]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_src_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_enum(srna, "layers_uv_select_src", DT_layers_select_src_items, DT_LAYERS_ALL_SRC,
+ "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_src[DT_MULTILAYER_INDEX_UV]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_src_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_enum(srna, "layers_vgroup_select_dst", DT_layers_select_dst_items, DT_LAYERS_NAME_DST,
+ "Destination Layers Matching", "How to match source and destination layers");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_dst[DT_MULTILAYER_INDEX_MDEFORMVERT]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_dst_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+#if 0
+ prop = RNA_def_enum(srna, "layers_shapekey_select_dst", DT_layers_select_dst_items, DT_LAYERS_NAME_DST,
+ "Destination Layers Matching", "How to match source and destination layers");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_dst[DT_MULTILAYER_INDEX_SHAPEKEY]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_dst_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+#endif
+
+ prop = RNA_def_enum(srna, "layers_vcol_select_dst", DT_layers_select_dst_items, DT_LAYERS_NAME_DST,
+ "Destination Layers Matching", "How to match source and destination layers");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_dst[DT_MULTILAYER_INDEX_VCOL]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_dst_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_enum(srna, "layers_uv_select_dst", DT_layers_select_dst_items, DT_LAYERS_NAME_DST,
+ "Destination Layers Matching", "How to match source and destination layers");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_dst[DT_MULTILAYER_INDEX_UV]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_dst_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* Mix stuff */
+ prop = RNA_def_enum(srna, "mix_mode", DT_mix_mode_items, CDT_MIX_TRANSFER, "Mix Mode",
+ "How to affect destination elements with source values");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_mix_mode_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_float(srna, "mix_factor", 1.0f, 0.0f, 1.0f, "Mix Factor",
+ "Factor to use when applying data to destination (exact behavior depends on mix mode)",
+ 0.0f, 1.0f);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_string(srna, "vertex_group", NULL, MAX_VGROUP_NAME, "Vertex Group",
+ "Vertex group name for selecting the affected areas");
+ RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DataTransferModifier_defgrp_name_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_boolean(srna, "invert_vertex_group", false, "Invert", "Invert vertex group influence");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_INVERT_VGROUP);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+}
+
void RNA_def_modifier(BlenderRNA *brna)
{
StructRNA *srna;
@@ -3920,6 +4430,7 @@ void RNA_def_modifier(BlenderRNA *brna)
rna_def_modifier_meshcache(brna);
rna_def_modifier_laplaciandeform(brna);
rna_def_modifier_wireframe(brna);
+ rna_def_modifier_datatransfer(brna);
}
#endif
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 06e9f8f5b67..a93dc76a655 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -52,6 +52,7 @@ set(SRC
intern/MOD_cloth.c
intern/MOD_collision.c
intern/MOD_curve.c
+ intern/MOD_datatransfer.c
intern/MOD_decimate.c
intern/MOD_displace.c
intern/MOD_dynamicpaint.c
diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h
index 9c7c21cc839..aceee441098 100644
--- a/source/blender/modifiers/MOD_modifiertypes.h
+++ b/source/blender/modifiers/MOD_modifiertypes.h
@@ -81,6 +81,7 @@ extern ModifierTypeInfo modifierType_UVWarp;
extern ModifierTypeInfo modifierType_MeshCache;
extern ModifierTypeInfo modifierType_LaplacianDeform;
extern ModifierTypeInfo modifierType_Wireframe;
+extern ModifierTypeInfo modifierType_DataTransfer;
/* MOD_util.c */
void modifier_type_init(ModifierTypeInfo *types[]);
diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c
new file mode 100644
index 00000000000..06f9d274576
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_datatransfer.c
@@ -0,0 +1,221 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): None yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/modifiers/intern/MOD_datatransfer.c
+ * \ingroup modifiers
+ */
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_customdata.h"
+#include "BKE_object_data_transfer.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_library.h"
+#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_remap.h"
+#include "BKE_modifier.h"
+#include "BKE_report.h"
+
+#include "MEM_guardedalloc.h"
+#include "MOD_util.h"
+
+#include "depsgraph_private.h"
+
+/**************************************
+ * Modifiers functions. *
+ **************************************/
+static void initData(ModifierData *md)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ int i;
+
+ dtmd->ob_source = NULL;
+ dtmd->data_types = 0;
+
+ dtmd->vmap_mode = MREMAP_MODE_VERT_NEAREST;
+ dtmd->emap_mode = MREMAP_MODE_EDGE_NEAREST;
+ dtmd->lmap_mode = MREMAP_MODE_LOOP_NEAREST_POLYNOR;
+ dtmd->pmap_mode = MREMAP_MODE_POLY_NEAREST;
+
+ dtmd->map_max_distance = 1.0f;
+ dtmd->map_ray_radius = 0.0f;
+
+ for (i = 0; i < DT_MULTILAYER_INDEX_MAX; i++) {
+ dtmd->layers_select_src[i] = DT_LAYERS_ALL_SRC;
+ dtmd->layers_select_dst[i] = DT_LAYERS_NAME_DST;
+ }
+
+ dtmd->mix_mode = CDT_MIX_TRANSFER;
+ dtmd->mix_factor = 1.0f;
+ dtmd->defgrp_name[0] = '\0';
+
+ dtmd->flags = MOD_DATATRANSFER_OBSRC_TRANSFORM;
+}
+
+static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ CustomDataMask dataMask = 0;
+
+ if (dtmd->defgrp_name[0]) {
+ /* We need vertex groups! */
+ dataMask |= CD_MASK_MDEFORMVERT;
+ }
+
+ dataMask |= BKE_object_data_transfer_dttypes_to_cdmask(dtmd->data_types);
+
+ return dataMask;
+}
+
+static bool dependsOnNormals(ModifierData *md)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ int item_types = BKE_object_data_transfer_get_dttypes_item_types(dtmd->data_types);
+
+ if ((item_types & ME_VERT) && (dtmd->vmap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
+ return true;
+ }
+ if ((item_types & ME_EDGE) && (dtmd->emap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
+ return true;
+ }
+ if ((item_types & ME_LOOP) && (dtmd->lmap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
+ return true;
+ }
+ if ((item_types & ME_POLY) && (dtmd->pmap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
+ return true;
+ }
+
+ return false;
+}
+
+static void foreachObjectLink(ModifierData *md, Object *ob,
+ void (*walk)(void *userData, Object *ob, Object **obpoin),
+ void *userData)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ walk(userData, ob, &dtmd->ob_source);
+}
+
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+}
+
+static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene),
+ Object *UNUSED(ob), DagNode *obNode)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ DagNode *curNode;
+
+ if (dtmd->ob_source) {
+ curNode = dag_get_node(forest, dtmd->ob_source);
+
+ dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
+ "DataTransfer Modifier");
+ }
+}
+
+static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ /* If no source object, bypass. */
+ return (dtmd->ob_source == NULL);
+}
+
+#define HIGH_POLY_WARNING 10000
+
+static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ ModifierApplyFlag UNUSED(flag))
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ DerivedMesh *dm = derivedData;
+ ReportList reports;
+
+ const bool invert_vgroup = (dtmd->flags & MOD_DATATRANSFER_INVERT_VGROUP) != 0;
+
+ const float max_dist = (dtmd->flags & MOD_DATATRANSFER_MAP_MAXDIST) ? dtmd->map_max_distance : FLT_MAX;
+
+ SpaceTransform space_transform_data;
+ SpaceTransform *space_transform = (dtmd->flags & MOD_DATATRANSFER_OBSRC_TRANSFORM) ? &space_transform_data : NULL;
+
+ if (space_transform) {
+ BLI_SPACE_TRANSFORM_SETUP(space_transform, ob, dtmd->ob_source);
+ }
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ /* Note: no islands precision for now here. */
+ BKE_object_data_transfer_dm(md->scene, dtmd->ob_source, ob, dm, dtmd->data_types, false,
+ dtmd->vmap_mode, dtmd->emap_mode, dtmd->lmap_mode, dtmd->pmap_mode,
+ space_transform, max_dist, dtmd->map_ray_radius, 0.0f,
+ dtmd->layers_select_src, dtmd->layers_select_dst,
+ dtmd->mix_mode, dtmd->mix_factor, dtmd->defgrp_name, invert_vgroup, &reports);
+
+ if (BKE_reports_contain(&reports, RPT_ERROR)) {
+ modifier_setError(md, "%s", BKE_reports_string(&reports, RPT_ERROR));
+ }
+ else if (dm->getNumVerts(dm) > HIGH_POLY_WARNING || ((Mesh *)(dtmd->ob_source->data))->totvert > HIGH_POLY_WARNING) {
+ modifier_setError(md, "You are using a rather high poly as source or destination, computation might be slow");
+ }
+
+ return dm;
+}
+
+
+ModifierTypeInfo modifierType_DataTransfer = {
+ /* name */ "DataTransfer",
+ /* structName */ "DataTransferModifierData",
+ /* structSize */ sizeof(DataTransferModifierData),
+ /* type */ eModifierTypeType_NonGeometrical,
+ /* flags */ eModifierTypeFlag_AcceptsMesh |
+ eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_UsesPreview,
+
+ /* copyData */ NULL,
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+ /* applyModifierEM */ NULL,
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepgraph */ updateDepgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+};
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index 8c62a0ba816..62a7ddefdf3 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -304,5 +304,6 @@ void modifier_type_init(ModifierTypeInfo *types[])
INIT_TYPE(MeshCache);
INIT_TYPE(LaplacianDeform);
INIT_TYPE(Wireframe);
+ INIT_TYPE(DataTransfer);
#undef INIT_TYPE
}