#!/usr/bin/env python3 """ Test cinema animation fallback when Blender is not available """ import os import sys import json from datetime import datetime # Test the import structure print("Testing cinema animation imports...") try: from py_scripts.blender_animator import BLENDER_AVAILABLE, BlenderGPSAnimator print(f"✅ Import successful - BLENDER_AVAILABLE: {BLENDER_AVAILABLE}") if not BLENDER_AVAILABLE: print("✅ Blender not available - fallback should work") # Test creating animator object (should not raise error now) try: animator = BlenderGPSAnimator("/tmp/test") print("✅ BlenderGPSAnimator created successfully (without Blender)") except Exception as e: print(f"❌ BlenderGPSAnimator creation failed: {e}") else: print("ℹ️ Blender is available on this system") except ImportError as e: print(f"❌ Import failed: {e}") # Test the cinema fallback logic by simulating it print("\nTesting cinema fallback logic...") try: # Import matplotlib dependencies import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np import cv2 print("✅ All cinema fallback dependencies available") # Test with sample GPS data sample_data = [ {"latitude": 45.0, "longitude": 25.0, "altitude": 100, "fixTime": "2025-01-01T10:00:00Z"}, {"latitude": 45.001, "longitude": 25.001, "altitude": 105, "fixTime": "2025-01-01T10:01:00Z"}, {"latitude": 45.002, "longitude": 25.002, "altitude": 110, "fixTime": "2025-01-01T10:02:00Z"}, ] # Process coordinates like the fallback code does lats = np.array([pos['latitude'] for pos in sample_data]) lons = np.array([pos['longitude'] for pos in sample_data]) alts = np.array([pos.get('altitude', 0) for pos in sample_data]) lat_center = np.mean(lats) lon_center = np.mean(lons) alt_min = np.min(alts) x = (lons - lon_center) * 111320 * np.cos(np.radians(lat_center)) y = (lats - lat_center) * 110540 z = alts - alt_min print(f"✅ GPS coordinate conversion successful") print(f" - X range: {np.min(x):.1f} to {np.max(x):.1f}") print(f" - Y range: {np.min(y):.1f} to {np.max(y):.1f}") print(f" - Z range: {np.min(z):.1f} to {np.max(z):.1f}") # Test creating a simple 3D plot fig = plt.figure(figsize=(12, 8), dpi=100) ax = fig.add_subplot(111, projection='3d') # Plot the path ax.plot(x, y, z, 'b-', linewidth=2, alpha=0.8, label='GPS Track') ax.scatter(x, y, z, c='red', s=50, alpha=0.8) ax.set_xlabel('East (m)') ax.set_ylabel('North (m)') ax.set_zlabel('Altitude (m)') ax.set_title('Cinema Animation Test') # Save test frame test_path = "/tmp/test_cinema_frame.png" plt.savefig(test_path, dpi=100, bbox_inches='tight', facecolor='black') plt.close() if os.path.exists(test_path): print(f"✅ Test cinema frame created: {test_path}") # Test OpenCV video creation fourcc = cv2.VideoWriter_fourcc(*'mp4v') video_path = "/tmp/test_cinema_video.mp4" video_writer = cv2.VideoWriter(video_path, fourcc, 24, (1200, 800)) # Read the frame and add it to video frame = cv2.imread(test_path) if frame is not None: resized_frame = cv2.resize(frame, (1200, 800)) video_writer.write(resized_frame) video_writer.release() if os.path.exists(video_path): print(f"✅ Test cinema video created: {video_path}") else: print("❌ Video file was not created") else: print("❌ Could not read test frame") else: print("❌ Test frame was not created") except Exception as e: print(f"❌ Cinema fallback test failed: {e}") import traceback traceback.print_exc() print("\nCinema animation fallback test complete!")