Minor refactoring to the camera class, with an additional change to z-buffering default behavior

This commit is contained in:
Grant Sanderson
2018-02-10 18:37:34 -08:00
parent 90e4951ef5
commit 5af31c1b8b

View File

@ -10,6 +10,10 @@ from helpers import *
from mobject import Mobject, PMobject, VMobject, \
ImageMobject, Group, BackgroundColoredVMobject
# Set a @profile decorator over any method whose
# performance you'd like to analyze
from profilehooks import profile
class Camera(object):
CONFIG = {
"background_image" : None,
@ -31,7 +35,11 @@ class Camera(object):
"image_mode" : "RGBA",
"n_rgb_coords" : 4,
"background_alpha" : 0, #Out of color_max_val
"pixel_array_dtype" : 'uint8'
"pixel_array_dtype" : 'uint8',
"use_z_coordinate_for_display_order" : False,
# z_buff_func is only used if the flag above is set to True.
# round z coordinate to nearest hundredth when comparring
"z_buff_func" : lambda m : np.round(m.get_center()[2], 2),
}
def __init__(self, background = None, **kwargs):
@ -94,7 +102,12 @@ class Camera(object):
return retval
def set_pixel_array(self, pixel_array, convert_from_floats = False):
self.pixel_array = self.convert_pixel_array(pixel_array, convert_from_floats)
converted_array = self.convert_pixel_array(pixel_array, convert_from_floats)
if not hasattr(self, "pixel_array"): #TODO: And the shapes match?
self.pixel_array = converted_array
else:
#Set in place
self.pixel_array[:,:,:] = converted_array[:,:,:]
def set_background(self, pixel_array, convert_from_floats = False):
self.background = self.convert_pixel_array(pixel_array, convert_from_floats)
@ -141,8 +154,6 @@ class Camera(object):
self, mobjects,
include_submobjects = True,
excluded_mobjects = None,
#Round z coordinate to nearest hundredth when comparring
z_buff_func = lambda m : np.round(m.get_center()[2], 2)
):
if include_submobjects:
mobjects = self.extract_mobject_family_members(
@ -154,15 +165,22 @@ class Camera(object):
)
mobjects = list_difference_update(mobjects, all_excluded)
# Should perhaps think about what happens here when include_submobjects is False,
# (for now, the onus is then on the caller to ensure this is handled correctly by
# passing us an appropriately pre-flattened list of mobjects if need be)
return sorted(mobjects, lambda a, b: cmp(z_buff_func(a), z_buff_func(b)))
if self.use_z_coordinate_for_display_order:
# Should perhaps think about what happens here when include_submobjects is False,
# (for now, the onus is then on the caller to ensure this is handled correctly by
# passing us an appropriately pre-flattened list of mobjects if need be)
return sorted(
mobjects,
lambda a, b: cmp(self.z_buff_func(a), self.z_buff_func(b))
)
else:
return mobjects
def capture_mobject(self, mobject, **kwargs):
return self.capture_mobjects([mobject], **kwargs)
def capture_mobjects(self, mobjects, **kwargs):
self.reset_aggdraw_canvas()
mobjects = self.get_mobjects_to_display(mobjects, **kwargs)
vmobjects = []
for mobject in mobjects:
@ -190,23 +208,32 @@ class Camera(object):
#TODO, more? Call out if it's unknown?
self.display_multiple_vectorized_mobjects(vmobjects)
## Methods associated with svg rendering
def get_aggdraw_canvas(self):
if not hasattr(self, "canvas"):
self.reset_aggdraw_canvas()
return self.canvas
def reset_aggdraw_canvas(self):
image = Image.fromarray(self.pixel_array, mode = self.image_mode)
self.canvas = aggdraw.Draw(image)
def display_multiple_vectorized_mobjects(self, vmobjects):
if len(vmobjects) == 0:
return
#More efficient to bundle together in one "canvas"
image = Image.fromarray(self.pixel_array, mode = self.image_mode)
canvas = aggdraw.Draw(image)
canvas = self.get_aggdraw_canvas()
for vmobject in vmobjects:
self.display_vectorized(vmobject, canvas)
canvas.flush()
self.pixel_array[:,:] = image
def display_vectorized(self, vmobject, canvas):
def display_vectorized(self, vmobject, canvas = None):
if vmobject.is_subpath:
#Subpath vectorized mobjects are taken care
#of by their parent
return
canvas = canvas or self.get_aggdraw_canvas()
pen, fill = self.get_pen_and_fill(vmobject)
pathstring = self.get_pathstring(vmobject)
symbol = aggdraw.Symbol(pathstring)
@ -280,7 +307,6 @@ class Camera(object):
self.pixel_array, array
)
def display_point_cloud(self, points, rgbas, thickness):
if len(points) == 0:
return