Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions manim/mobject/graphing/number_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,23 @@ def get_number_mobject(
num_mob.shift(num_mob[0].width * LEFT / 2)
return num_mob

def default_numbers_to_display(self) -> np.ndarray:
"""Returns the default numbers to display on the number line.

This method returns the tick range excluding numbers that are in
the numbers_to_exclude list.

Returns
-------
np.ndarray
Array of numbers that should be displayed by default.
"""
tick_range = self.get_tick_range()
if self.numbers_to_exclude:
# Filter out excluded numbers
return np.array([x for x in tick_range if x not in self.numbers_to_exclude])
return tick_range

def get_number_mobjects(self, *numbers: float, **kwargs: Any) -> VGroup:
if len(numbers) == 0:
numbers = self.default_numbers_to_display()
Expand Down
29 changes: 28 additions & 1 deletion manim/mobject/opengl/opengl_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -2683,7 +2683,34 @@ def construct(self):

func = path_func if key in ("points", "bounding_box") else interpolate

self.data[key][:] = func(mobject1.data[key], mobject2.data[key], alpha)
# Check for shape compatibility before interpolation
arr1 = mobject1.data[key]
arr2 = mobject2.data[key]
target_arr = self.data[key]

try:
interpolated_data = func(arr1, arr2, alpha)
# Ensure the interpolated data has compatible shape with target array
if target_arr.shape != interpolated_data.shape:
# If shapes don't match, try to resize target array to match interpolated data
if hasattr(interpolated_data, "shape"):
# For numpy arrays, copy the data directly
self.data[key] = interpolated_data.copy()
else:
# For other data types, assign directly
self.data[key] = interpolated_data
else:
target_arr[:] = interpolated_data
except (ValueError, TypeError):
# If interpolation fails due to shape mismatch, fall back to mobject2 data
# This ensures animations don't crash with very short run times
if hasattr(arr2, "shape"):
if target_arr.shape != arr2.shape:
self.data[key] = arr2.copy()
else:
target_arr[:] = arr2
else:
self.data[key] = arr2

for key in self.uniforms:
if key != "fixed_orientation_center":
Expand Down
11 changes: 10 additions & 1 deletion manim/renderer/opengl_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,16 @@ def play(
self.animation_elapsed_time = scene.duration

else:
scene.play_internal()
# If animations are being skipped due to caching, we still need to
# properly interpolate animations to their end state to ensure
# ValueTrackers and always_redraw functions have correct values
if self.skip_animations:
# Ensure all animations reach their final state
scene.update_to_time(scene.duration)
# Update all mobjects to reflect the final animation state
scene.update_mobjects(0)
else:
scene.play_internal()

self.file_writer.end_animation(not self.skip_animations)
self.time += scene.duration
Expand Down
Loading