Browse Source

Add Bake Image Alpha operator.

pull/176/head
Adam Johnson 5 years ago
parent
commit
212c776db4
Signed by: Hoikas
GPG Key ID: 0B6515D6FF6F271E
  1. 79
      korman/operators/op_image.py
  2. 27
      korman/ui/ui_menus.py

79
korman/operators/op_image.py

@ -33,13 +33,82 @@ _CUBE_FACES = {
"frontFace": "FR",
}
class ImageOperator:
class PlasmaBakeImageAlphaOperator(bpy.types.Operator):
bl_idname = "image.plasma_bake_image_alpha"
bl_label = "Bake Image Alpha"
bl_description = "Bake an image's calculated alpha to another image's alpha channel"
filepath = StringProperty(name="Alpha Image",
subtype="FILE_PATH",
options=set())
def execute(self, context):
with ConsoleToggler(True), ExportProgressLogger() as self._report:
try:
self._execute(context)
except ExportError as error:
self.report({"ERROR"}, str(error))
return {"CANCELLED"}
else:
return {"FINISHED"}
def _execute(self, context):
self._report.progress_add_step("Preparing Images")
self._report.progress_add_step("Baking Alpha")
self._report.progress_add_step("Creating Image")
self._report.progress_start("BAKING IMAGE ALPHA")
if not Path(self.filepath).is_file():
raise ExportError("No image found at '{}'".format(self.filepath))
self._report.progress_advance()
images, im_diffuse = bpy.data.images, context.space_data.image
with TemporaryObject(images.load(self.filepath), images.remove) as im_alpha:
width, height = self._check_image_scale(im_diffuse, im_alpha)
self._report.progress_advance()
pixels = self._calc_alpha(im_diffuse, im_alpha, width, height)
self._report.progress_advance()
self._make_image(im_diffuse.name, self.filepath, width, height, pixels, context)
self._report.progress_end()
def _check_image_scale(self, im_diffuse, im_alpha):
sz_diffuse, sz_alpha = tuple(im_diffuse.size), tuple(im_alpha.size)
if tuple(im_diffuse.size) != tuple(im_alpha.size):
self._report.warn("Image sizes do not match, rescaling alpha image")
im_alpha.scale(*sz_diffuse)
return sz_diffuse
def _calc_alpha(self, im_diffuse, im_alpha, width, height):
# DO NOT REMOVE this copying... Trying to operate directly on the bpy_prop_collection
# is slower than molasses running uphill in Siberia!
pixels_diffuse, pixels_alpha = list(im_diffuse.pixels), tuple(im_alpha.pixels)
for i in range(width * height):
alpha_idx = i * 4
pixels_diffuse[alpha_idx + 3] = sum(pixels_alpha[alpha_idx:alpha_idx+2]) / 3.0
return pixels_diffuse
def _make_image(self, name_diffuse, name_alpha, width, height, pixels, context=None):
name = "{}_ALPHAGEN_{}.png".format(Path(name_diffuse).stem, Path(name_alpha).stem)
im_dest = bpy.data.images.new(name, width, height, True)
im_dest.pixels = pixels
im_dest.update()
im_dest.pack(as_png=True)
if context and context.space_data:
context.space_data.image = im_dest
return im_dest
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {"RUNNING_MODAL"}
@classmethod
def poll(cls, context):
return context.scene.render.engine == "PLASMA_GAME"
space = context.space_data
return context.scene.render.engine == "PLASMA_GAME" and space and space.image
class PlasmaBuildCubeMapOperator(ImageOperator, bpy.types.Operator):
class PlasmaBuildCubeMapOperator(bpy.types.Operator):
bl_idname = "image.plasma_build_cube_map"
bl_label = "Build Cubemap"
bl_description = "Builds a Blender cubemap from six images"
@ -207,6 +276,10 @@ class PlasmaBuildCubeMapOperator(ImageOperator, bpy.types.Operator):
with GLTexture(image=blimage, fast=True) as glimage:
return glimage.image_data
@classmethod
def poll(cls, context):
return context.scene.render.engine == "PLASMA_GAME"
def _scale_images(self, face_widths, face_heights, face_data):
self._report.progress_advance()
self._report.progress_range = len(BLENDER_CUBE_MAP)

27
korman/ui/ui_menus.py

@ -13,7 +13,8 @@
# You should have received a copy of the GNU General Public License
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
from ..operators.op_mesh import *
import bpy
import functools
class PlasmaMenu:
@classmethod
@ -32,14 +33,30 @@ class PlasmaAddMenu(PlasmaMenu, bpy.types.Menu):
layout.operator("mesh.plasma_ladder_add", text="Ladder", icon="COLLAPSEMENU")
def build_plasma_menu(self, context):
class PlasmaImageMenu(PlasmaMenu, bpy.types.Menu):
bl_idname = "menu.plasma_image"
bl_label = "Plasma"
bl_description = "Plasma Image Operators"
def draw(self, context):
layout = self.layout
layout.operator("image.plasma_bake_image_alpha", icon="IMAGE_RGB_ALPHA")
def _build_plasma_menu(menu_operator, self, context):
if context.scene.render.engine != "PLASMA_GAME":
return
self.layout.separator()
self.layout.menu("menu.plasma_add", icon="URL")
self.layout.menu(menu_operator, icon="URL")
build_plasma_add_menu = functools.partial(_build_plasma_menu, "menu.plasma_add")
build_plasma_image_menu = functools.partial(_build_plasma_menu, "menu.plasma_image")
def register():
bpy.types.INFO_MT_add.append(build_plasma_menu)
bpy.types.INFO_MT_add.append(build_plasma_add_menu)
bpy.types.IMAGE_MT_image.append(build_plasma_image_menu)
def unregister():
bpy.types.INFO_MT_add.remove(build_plasma_menu)
bpy.types.INFO_MT_add.remove(build_plasma_add_menu)
bpy.types.IMAGE_MT_image.remove(build_plasma_image_menu)

Loading…
Cancel
Save