Skip to content

Commit

Permalink
fix: graceful update from Texture to ImageTexture in LightEffect so w…
Browse files Browse the repository at this point in the history
…e don't mess up old saved files
  • Loading branch information
ntamas committed Jul 10, 2023
1 parent 4ecf2f5 commit 63b33f6
Showing 1 changed file with 46 additions and 22 deletions.
68 changes: 46 additions & 22 deletions src/modules/sbstudio/plugin/model/light_effects.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
ColorRamp,
Context,
Image,
ImageTexture,
PropertyGroup,
Mesh,
Object,
ImageTexture,
Texture,
)
from mathutils import Vector
from mathutils.bvhtree import BVHTree
Expand Down Expand Up @@ -187,7 +188,7 @@ class LightEffect(PropertyGroup):
)

texture = PointerProperty(
type=ImageTexture,
type=Texture,
name="Texture",
description=(
"Texture of the light effect, used for the sole purpose of having a "
Expand Down Expand Up @@ -417,22 +418,29 @@ def apply_on_colors(
@property
def color_ramp(self) -> Optional[ColorRamp]:
"""The color ramp of the effect, if exists and is used."""
return (
self.texture.color_ramp
if self.texture and self.color_image is None
else None
)
tex = self.texture
if isinstance(tex, ImageTexture):
return tex.color_ramp if tex.image is None else None
else:
return tex.color_ramp

@property
def color_image(self) -> Optional[Image]:
"""The color image of the effect, if exists."""
return self.texture.image if self.texture else None
return self.texture.image if isinstance(self.texture, ImageTexture) else None

@color_image.setter
def color_image(self, image):
if self.texture.image is not None:
bpy.data.images.remove(self.texture.image)
self.texture.image = image
# If we have an old, legacy Texture instance, replace it with an
# ImageTexture
if not isinstance(self.texture, ImageTexture):
self._remove_texture()
self._create_texture()

tex = self.texture
if tex.image is not None:
remove_if_unused(tex.image, from_=bpy.data.images)
tex.image = image

def contains_frame(self, frame: int) -> bool:
"""Returns whether the light effect contains the given frame.
Expand Down Expand Up @@ -560,6 +568,31 @@ def _get_spatial_effect_predicate(self) -> Optional[Callable[[Coordinate3D], boo
plane = self._get_plane_from_mesh()
return partial(test_is_in_front_of, plane)

def _create_texture(self) -> None:
"""Creates the texture associated to the light effect."""
tex = bpy.data.textures.new(
name=f"Texture for light effect {self.name!r}", type="IMAGE"
)
tex.use_color_ramp = True
tex.image = None

# Clear alpha from color ramp
elts = tex.color_ramp.elements
for elt in elts:
elt.color[3] = 1.0

self.texture = tex

def _remove_texture(self) -> None:
"""Removes the texture associated to the light effect from the Textures
collection if there are no other users for the texture in the scene.
"""
if isinstance(self.texture, ImageTexture):
if self.texture.image is not None:
remove_if_unused(self.texture.image, from_=bpy.data.images)

remove_if_unused(self.texture, from_=bpy.data.textures)


class LightEffectCollection(PropertyGroup, ListMixin):
"""Blender property group representing the list of light effects to apply
Expand Down Expand Up @@ -622,16 +655,7 @@ def append_new_entry(
entry.duration = duration
entry.name = name

entry.texture = bpy.data.textures.new(
name="Texture for light effect '{}'".format(name), type="IMAGE"
)
entry.texture.use_color_ramp = True
entry.texture.image = None

# Clear alpha from color ramp
elts = entry.texture.color_ramp.elements
for elt in elts:
elt.color[3] = 1.0
entry._create_texture()

# Copy default colors from the LED Control panel
if hasattr(scene, "skybrush") and hasattr(scene.skybrush, "led_control"):
Expand Down Expand Up @@ -723,5 +747,5 @@ def iter_active_effects_in_frame(self, frame: int) -> Iterable[LightEffect]:
yield entry

def _on_removing_entry(self, entry) -> bool:
remove_if_unused(entry.texture, from_=bpy.data.textures)
entry._remove_texture()
return True

0 comments on commit 63b33f6

Please sign in to comment.