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.
This commit is contained in:
Bastien Montagne 2015-01-09 21:19:12 +01:00
parent 8615977624
commit 79d8617424
17 changed files with 1442 additions and 16 deletions

View File

@ -26,6 +26,137 @@
id="title49470">Blender icons v. 2.5.08</title>
<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
@ -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"

Before

Width:  |  Height:  |  Size: 4.3 MiB

After

Width:  |  Height:  |  Size: 4.3 MiB

View File

@ -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__)

View File

@ -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))

View File

@ -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)

View File

@ -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");

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -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__ */

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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[]);

View File

@ -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,
};

View File

@ -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
}