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

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Nell <codemanx@gmx.de>2012-11-25 16:58:35 +0400
committerSebastian Nell <codemanx@gmx.de>2012-11-25 16:58:35 +0400
commitf39ad0af451520aa91744da7bc672a53c7e862ea (patch)
tree4a74508cad2f1ebcebcaf3e268770dbc24f2eb81 /uv_bake_texture_to_vcols.py
parentc89bae24333a005568b96542974288162b216cf3 (diff)
Moving UV Bake script from contrib to trunk.
[[Split portion of a mixed commit.]]
Diffstat (limited to 'uv_bake_texture_to_vcols.py')
-rw-r--r--uv_bake_texture_to_vcols.py348
1 files changed, 348 insertions, 0 deletions
diff --git a/uv_bake_texture_to_vcols.py b/uv_bake_texture_to_vcols.py
new file mode 100644
index 00000000..802a3033
--- /dev/null
+++ b/uv_bake_texture_to_vcols.py
@@ -0,0 +1,348 @@
+# ##### 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.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+"""
+Bake UV-Texture to Vertex Colors Addon
+
+Contact: p_boelens@msn.com
+Information: http://projects.blender.org/tracker/index.php?func=detail&aid=28211
+
+Contributor(s): Patrick Boelens, CoDEmanX.
+
+All rights reserved.
+"""
+
+bl_info = {
+ "name": "Bake UV-Texture to Vertex Colors",
+ "description": "Bakes the colors of the active UV Texture to a Vertex Color layer. ",
+ "author": "Patrick Boelens, CoDEmanX",
+ "version": (0, 6),
+ "blender": (2, 6, 3),
+ "location": "3D View > Vertex Paint > Toolshelf > Bake",
+ "warning": "Requires image texture, generated textures aren't supported.",
+ "wiki_url": "http://wiki.blender.org/index.php?title=Extensions:2.6/"
+ "Py/Scripts/UV/Bake_Texture_to_Vertex_Colors",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=28211",
+ "category": "UV"}
+
+import bpy
+from bpy.props import BoolProperty, EnumProperty, FloatVectorProperty
+from math import fabs
+from colorsys import rgb_to_hsv, hsv_to_rgb
+
+class UV_OT_bake_texture_to_vcols(bpy.types.Operator):
+ bl_idname = "uv.bake_texture_to_vcols"
+ bl_label = "Bake UV-Texture to Vertex Colors"
+ bl_description = "Bake active UV-Texture to new Vertex Color layer (requires image texture)"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ replace_active_layer = BoolProperty(name="Replace layer",
+ description="Overwrite active Vertex Color layer",
+ default=True)
+
+ mappingModes = [("CLIP", "Clip", "Don't affect vertices who's UV-coordinates are out of bounds."),
+ ("REPEAT", "Repeat", "Tile the image so that each vertex is accounted for."),
+ ("EXTEND", "Extend", "Extends the edges of the image to the UV-coordinates.")
+ ]
+
+ mappingMode = EnumProperty(items=mappingModes,
+ default="CLIP",
+ name="Mapping",
+ description="The mode to use for baking vertices who's UV-coordinates are out of bounds.")
+
+ blendingModes = [("MIX", "Mix", ""),
+ ("ADD", "Add", ""),
+ ("SUBTRACT", "Subtract", ""),
+ ("MULTIPLY", "Multiply", ""),
+ ("SCREEN", "Screen", ""),
+ ("OVERLAY", "Overlay", ""),
+ ("DIFFERENCE", "Difference", ""),
+ ("DIVIDE", "Divide", ""),
+ ("DARKEN", "Darken", ""),
+ ("LIGHTEN", "Lighten", ""),
+ ("HUE", "Hue", ""),
+ ("SATURATION", "Saturation", ""),
+ ("VALUE", "Value", ""),
+ ("COLOR", "Color", ""),
+ ("SOFT_LIGHT", "Soft Light", ""),
+ ("LINEAR_LIGHT", "Linear Light", "")
+ ]
+
+ blendingMode = EnumProperty(items=blendingModes,
+ default="MULTIPLY",
+ name="Blend Type",
+ description="The blending mode to use when baking")
+
+ mirror_x = BoolProperty(name="Mirror X", description="Mirror the image on the X-axis.")
+ mirror_y = BoolProperty(name="Mirror Y", description="Mirror the image on the Y-axis.")
+
+ @classmethod
+ def poll(self, context):
+ return (context.object and
+ context.object.type == 'MESH' and
+ context.mode != 'EDIT_MESH' and
+ context.object.data.uv_layers.active and
+ context.object.data.uv_textures.active)
+
+ def execute(self, context):
+ obdata = context.object.data
+
+ if self.replace_active_layer and obdata.vertex_colors.active:
+ vertex_colors = obdata.vertex_colors.active
+ else:
+ vertex_colors = obdata.vertex_colors.new(name="Baked UV texture")
+
+ if not vertex_colors:
+ # Can't add more than 17 VCol layers
+ self.report({'ERROR'}, "Couldn't add another Vertex Color layer,\n"
+ "Please remove an existing layer or replace active.")
+ return {'CANCELLED'}
+
+ obdata.vertex_colors.active = vertex_colors
+
+ uv_images = {}
+ for uv_tex in obdata.uv_textures.active.data:
+ if uv_tex.image and uv_tex.image.name not in uv_images and uv_tex.image.pixels:
+
+ uv_images[uv_tex.image.name] = (uv_tex.image.size[0],
+ uv_tex.image.size[1],
+ uv_tex.image.pixels[:]
+ # Accessing pixels directly is far too slow.
+ # Copied to new array for massive performance-gain.
+ )
+
+ for p in obdata.polygons:
+ img = obdata.uv_textures.active.data[p.index].image
+ if not img:
+ continue
+
+ image_size_x, image_size_y, uv_pixels = uv_images[img.name]
+
+ for loop in p.loop_indices:
+
+ co = obdata.uv_layers.active.data[loop].uv
+ x_co = round(co[0] * (image_size_x - 1))
+ y_co = round(co[1] * (image_size_y - 1))
+
+ if x_co < 0 or x_co >= image_size_x or y_co < 0 or y_co >= image_size_y:
+ if self.mappingMode == 'CLIP':
+ continue
+
+ elif self.mappingMode == 'REPEAT':
+ x_co %= image_size_x
+ y_co %= image_size_y
+
+ elif self.mappingMode == 'EXTEND':
+ if x_co > image_size_x - 1:
+ x_co = image_size_x - 1
+ if x_co < 0:
+ x_co = 0
+ if y_co > image_size_y - 1:
+ y_co = image_size_y - 1
+ if y_co < 0:
+ y_co = 0
+
+ if self.mirror_x:
+ x_co = image_size_x -1 - x_co
+
+ if self.mirror_y:
+ y_co = image_size_y -1 - y_co
+
+ col_out = vertex_colors.data[loop].color
+
+ pixelNumber = (image_size_x * y_co) + x_co
+ r = uv_pixels[pixelNumber*4]
+ g = uv_pixels[pixelNumber*4 + 1]
+ b = uv_pixels[pixelNumber*4 + 2]
+ a = uv_pixels[pixelNumber*4 + 3]
+
+ col_in = r, g, b # texture-color
+ col_result = [r,g,b] # existing / 'base' color
+
+ if self.blendingMode == 'MIX':
+ col_result = col_in
+
+ elif self.blendingMode == 'ADD':
+ col_result[0] = col_in[0] + col_out[0]
+ col_result[1] = col_in[1] + col_out[1]
+ col_result[2] = col_in[2] + col_out[2]
+
+ elif self.blendingMode == 'SUBTRACT':
+ col_result[0] = col_in[0] - col_out[0]
+ col_result[1] = col_in[1] - col_out[1]
+ col_result[2] = col_in[2] - col_out[2]
+
+ elif self.blendingMode == 'MULTIPLY':
+ col_result[0] = col_in[0] * col_out[0]
+ col_result[1] = col_in[1] * col_out[1]
+ col_result[2] = col_in[2] * col_out[2]
+
+ elif self.blendingMode == 'SCREEN':
+ col_result[0] = 1 - (1.0 - col_in[0]) * (1.0 - col_out[0])
+ col_result[1] = 1 - (1.0 - col_in[1]) * (1.0 - col_out[1])
+ col_result[2] = 1 - (1.0 - col_in[2]) * (1.0 - col_out[2])
+
+ elif self.blendingMode == 'OVERLAY':
+ if col_out[0] < 0.5:
+ col_result[0] = col_out[0] * (2.0 * col_in[0])
+ else:
+ col_result[0] = 1.0 - (2.0 * (1.0 - col_in[0])) * (1.0 - col_out[0])
+ if col_out[1] < 0.5:
+ col_result[1] = col_out[1] * (2.0 * col_in[1])
+ else:
+ col_result[1] = 1.0 - (2.0 * (1.0 - col_in[1])) * (1.0 - col_out[1])
+ if col_out[2] < 0.5:
+ col_result[2] = col_out[2] * (2.0 * col_in[2])
+ else:
+ col_result[2] = 1.0 - (2.0 * (1.0 - col_in[2])) * (1.0 - col_out[2])
+
+ elif self.blendingMode == 'DIFFERENCE':
+ col_result[0] = fabs(col_in[0] - col_out[0])
+ col_result[1] = fabs(col_in[1] - col_out[1])
+ col_result[2] = fabs(col_in[2] - col_out[2])
+
+ elif self.blendingMode == 'DIVIDE':
+ if(col_in[0] != 0.0):
+ col_result[0] = col_out[0] / col_in[0]
+ if(col_in[1] != 0.0):
+ col_result[0] = col_out[1] / col_in[1]
+ if(col_in[2] != 0.0):
+ col_result[2] = col_out[2] / col_in[2]
+
+ elif self.blendingMode == 'DARKEN':
+ if col_in[0] < col_out[0]:
+ col_result[0] = col_in[0]
+ else:
+ col_result[0] = col_out[0]
+ if col_in[1] < col_out[1]:
+ col_result[1] = col_in[1]
+ else:
+ col_result[1] = col_out[1]
+ if col_in[2] < col_out[2]:
+ col_result[2] = col_in[2]
+ else:
+ col_result[2] = col_out[2]
+
+
+ elif self.blendingMode == 'LIGHTEN':
+ if col_in[0] > col_out[0]:
+ col_result[0] = col_in[0]
+ else:
+ col_result[0] = col_out[0]
+ if col_in[1] > col_out[1]:
+ col_result[1] = col_in[1]
+ else:
+ col_result[1] = col_out[1]
+ if col_in[2] > col_out[2]:
+ col_result[2] = col_in[2]
+ else:
+ col_result[2] = col_out[2]
+
+ elif self.blendingMode == 'HUE':
+ hsv_in = rgb_to_hsv(col_in[0], col_in[1], col_in[2])
+ hsv_out = rgb_to_hsv(col_out[0], col_out[1], col_out[2])
+ hue = hsv_in[0]
+ col_result = hsv_to_rgb(hue, hsv_out[1], hsv_out[2])
+
+ elif self.blendingMode == 'SATURATION':
+ hsv_in = rgb_to_hsv(col_in[0], col_in[1], col_in[2])
+ hsv_out = rgb_to_hsv(col_out[0], col_out[1], col_out[2])
+ sat = hsv_in[1]
+ col_result = hsv_to_rgb(hsv_out[0], sat, hsv_out[2])
+
+ elif self.blendingMode == 'VALUE':
+ hsv_in = rgb_to_hsv(col_in[0], col_in[1], col_in[2])
+ hsv_out = rgb_to_hsv(col_out[0], col_out[1], col_out[2])
+ val = hsv_in[2]
+ col_result = hsv_to_rgb(hsv_out[0], hsv_out[1], val)
+
+ elif self.blendingMode == 'COLOR':
+ hsv_in = rgb_to_hsv(col_in[0], col_in[1], col_in[2])
+ hsv_out = rgb_to_hsv(col_out[0], col_out[1], col_out[2])
+ hue = hsv_in[0]
+ sat = hsv_in[1]
+ col_result = hsv_to_rgb(hue, sat, hsv_out[2])
+
+ elif self.blendingMode == 'SOFT_LIGHT':
+ scr = 1 - (1.0 - col_in[0]) * (1.0 - col_out[0])
+ scg = 1 - (1.0 - col_in[1]) * (1.0 - col_out[1])
+ scb = 1 - (1.0 - col_in[2]) * (1.0 - col_out[2])
+
+ col_result[0] = (1.0 - col_out[0]) * (col_in[0] * col_out[0]) + (col_out[0] * scr)
+ col_result[1] = (1.0 - col_out[1]) * (col_in[1] * col_out[1]) + (col_out[1] * scg)
+ col_result[2] = (1.0 - col_out[2]) * (col_in[2] * col_out[2]) + (col_out[2] * scb)
+
+
+ elif self.blendingMode == 'LINEAR_LIGHT':
+ if col_in[0] > 0.5:
+ col_result[0] = col_out[0] + 2.0 * (col_in[0] - 0.5)
+ else:
+ col_result[0] = col_out[0] + 2.0 * (col_in[0] - 1.0)
+ if col_in[1] > 0.5:
+ col_result[1] = col_out[1] + 2.0 * (col_in[1] - 0.5)
+ else:
+ col_result[1] = col_out[1] + 2.0 * (col_in[1] - 1.0)
+ if col_in[2] > 0.5:
+ col_result[2] = col_out[2] + 2.0 * (col_in[2] - 0.5)
+ else:
+ col_result[2] = col_out[2] + 2.0 * (col_in[2] - 1.0)
+
+ # Add alpha color
+ a_inverted = 1 - a
+ alpha_color = context.scene.uv_bake_alpha_color
+ col_result = (col_result[0] * a + alpha_color[0] * a_inverted,
+ col_result[1] * a + alpha_color[1] * a_inverted,
+ col_result[2] * a + alpha_color[2] * a_inverted)
+
+ vertex_colors.data[loop].color = col_result
+
+ return {'FINISHED'}
+
+class VIEW3D_PT_tools_uv_bake_texture_to_vcols(bpy.types.Panel):
+ bl_label = "Bake"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOLS"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(self, context):
+ return(context.mode == 'PAINT_VERTEX')
+
+ def draw(self, context):
+ layout = self.layout
+ col = layout.column()
+ col.prop(context.scene, "uv_bake_alpha_color")
+ col.separator()
+ col.operator("uv.bake_texture_to_vcols", text="UV Texture to VCols")
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.Scene.uv_bake_alpha_color = FloatVectorProperty(name="Alpha Color",
+ description="Color to be used for transparency",
+ subtype='COLOR',
+ min=0.0,
+ max=1.0)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ del bpy.types.Scene.uv_bake_alpha_color
+
+if __name__ == "__main__":
+ register() \ No newline at end of file