Transfer data: add modifier.
authorBastien Montagne <montagne29@wanadoo.fr>
Fri, 9 Jan 2015 20:19:12 +0000 (21:19 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Fri, 9 Jan 2015 23:04:43 +0000 (00:04 +0100)
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.

17 files changed:
release/datafiles/blender_icons.svg
release/datafiles/blender_icons16/icon16_mod_data_transfer.dat [new file with mode: 0644]
release/datafiles/blender_icons32/icon32_mod_data_transfer.dat [new file with mode: 0644]
release/scripts/startup/bl_ui/properties_data_modifier.py
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/editors/include/UI_icons.h
source/blender/editors/object/object_data_transfer.c
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_modifier.c
source/blender/editors/space_outliner/outliner_draw.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_modifier.c
source/blender/modifiers/CMakeLists.txt
source/blender/modifiers/MOD_modifiertypes.h
source/blender/modifiers/intern/MOD_datatransfer.c [new file with mode: 0644]
source/blender/modifiers/intern/MOD_util.c

index ed5e84778f929981d664ffc4adae97a12195a9d6..8fa93b412a676754f84c3f8c992709995ac7fc72 100644 (file)
      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
        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"
      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"
        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 (file)
index 0000000..53b5d3e
Binary files /dev/null and b/release/datafiles/blender_icons16/icon16_mod_data_transfer.dat 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 (file)
index 0000000..a405606
Binary files /dev/null and b/release/datafiles/blender_icons32/icon32_mod_data_transfer.dat differ
index 7a96996391180737847456685532f377b35808b7..e13d007a6d6a77336b3a0b951b3be80c93ccf379 100644 (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__)
index 268c911fc54ebdd925cce96974ede3cbebe20ac9..abc544ea70eadd28a9544f1e2c65d9b557e6cdb8 100644 (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))
index 618fa44349edb39b948e677c00eb8dfcb3e369e7..2313ccfc69b17a88d7baf76e22abb6c3759e9f87 100644 (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)
index 1d994746ba6a0b41386914a5c507d87c14524f8a..8dfd31c92bb11e2f36f3dfdd68cd298e1e2583c4 100644 (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");
index bcf77d819fe08b67395d367116c1ce8a492d5474..207afdf1028c806c814f73e65a5663d826962267 100644 (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);
index 97556365466b7620ec91a9946b6853768b5d3aa2..5a479af83b588e64dedc49ab5a16f9c00a377201 100644 (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;
index 3df6bd51f37dbfd3a1bc85b7dca9d7e1c6c9da65..a963f422cb7cda088370109ca32d0ee94da1e4a0 100644 (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:
index 47782bb3ae13f649088500ebb5d861728988ca59..b1e9fd254e1b06f358cc023a47e73fb28e9d104d 100644 (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__ */
index 0a1eb102d8cb64b710f6593e4d90ba82724f638a..6167164a7ac91651c663d3d644b5bb81eae532ca 100644 (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;
index 1cd646b19144f05379ed7ab16ae6c62e51beae84..9780c45867e0ed1c106467078fb75c7ded3c91fd 100644 (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
index 06e9f8f5b678a028551823bc4b431da5fa214189..a93dc76a655eb388b1db908708e3030d3ce4de86 100644 (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
index 9c7c21cc83901c692d62d9a3f1b76ecb877a5693..aceee4410984640a9816968edc159d13cab0b865 100644 (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[]);
diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c
new file mode 100644 (file)
index 0000000..06f9d27
--- /dev/null
@@ -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,
+};
index 8c62a0ba816a5b7b5509ad217f33f5b231446f39..62a7ddefdf312d33a7bcc477b641bcfe15f744be 100644 (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
 }