Spaces:
Sleeping
Sleeping
| import pyvista as pv | |
| pv.start_xvfb() | |
| # Configuration - Set input_vtp_path to your VTP file or leave None for default | |
| # e.g., "path/to/your/file.vtp" | |
| dataset = "plane_transonic_48" | |
| #input_mesh_path = f"Data/{dataset[:-3]}/{dataset}.vtp" # Input geometry mesh | |
| #output_mesh_path = f"metrics/{dataset[:-3]}/Transformer_baseline-variable-velocity-long/vtk_files/{dataset}.vtk" # Results with pressure fields | |
| # Configuration - Set paths for input mesh and output results | |
| input_mesh_path = f"Data/{dataset[:-3]}/{dataset}.vtp" # Input geometry mesh | |
| output_mesh_path = f"metrics/{dataset[:-3]}/Transformer_baseline_ep1000/vtk_files/{dataset}.vtk" # Results with pressure fields | |
| # Load input mesh (geometry only) | |
| print(f"Loading input mesh: {input_mesh_path}") | |
| input_mesh = pv.read(input_mesh_path) | |
| print(f"Input mesh info: {input_mesh.n_points} points, {input_mesh.n_cells} cells") | |
| # Load output mesh (with pressure fields) | |
| print(f"Loading output mesh: {output_mesh_path}") | |
| output_mesh = pv.read(output_mesh_path) | |
| print("Available fields in output mesh:", output_mesh.array_names) | |
| print(f"Output mesh type: {type(output_mesh)}") | |
| print(f"Output mesh info: {output_mesh.n_points} points, {output_mesh.n_cells} cells") | |
| # Check mesh cell types to understand the data structure | |
| if hasattr(output_mesh, 'celltypes'): | |
| unique_types = set(output_mesh.celltypes) | |
| print(f"Cell types in mesh: {unique_types}") | |
| # ParaView likely treats this as a surface - force surface rendering | |
| print("Converting to surface representation like ParaView...") | |
| if output_mesh.n_cells > 0: | |
| # If it has cells but they're vertices, convert to proper surface | |
| if output_mesh.n_points == output_mesh.n_cells: | |
| print("Point cloud data - using points as surface") | |
| # Keep as is but ensure proper rendering | |
| else: | |
| print("Extracting outer surface...") | |
| output_mesh = output_mesh.extract_surface() | |
| print(f"Final mesh: {output_mesh.n_points} points, {output_mesh.n_cells} cells") | |
| # Input mesh is already clean (no need to remove arrays) | |
| output_name = dataset | |
| # Get pressure ranges for consistent colorbars from output mesh | |
| gt_pressure = output_mesh["gt_pressure"] | |
| pred_pressure = output_mesh["pred_pressure"] | |
| pressure_min = min(gt_pressure.min(), pred_pressure.min()) | |
| pressure_max = max(gt_pressure.max(), pred_pressure.max()) | |
| pressure_range = [pressure_min, pressure_max] | |
| # Create plotter with 3 columns, 1 row | |
| plotter = pv.Plotter(shape=(1, 3), off_screen=True, window_size=(1920, 540)) # 16:9 aspect ratio for presentations | |
| # Set black background and consistent camera settings for all subplots | |
| for i in range(3): | |
| plotter.subplot(0, i) | |
| plotter.set_background('black') | |
| # Column 1: Input (Solid STL) | |
| plotter.subplot(0, 0) | |
| actor = plotter.add_mesh(input_mesh, color="white", | |
| show_edges=False, edge_color="black", line_width=1, | |
| smooth_shading=False, show_scalar_bar=False) | |
| # Column 2: Ground Truth | |
| plotter.subplot(0, 1) | |
| # Force surface-like rendering similar to ParaView | |
| actor = plotter.add_mesh(output_mesh, scalars="gt_pressure", clim=pressure_range, cmap="jet", | |
| show_edges=False, smooth_shading=False, show_scalar_bar=False, | |
| render_points_as_spheres=False, | |
| point_size=3.0, # Larger points if it's point cloud | |
| style='surface') # Force surface style | |
| plotter.add_scalar_bar(title='Pressure', title_font_size=18, label_font_size=18, | |
| position_x=0.1, position_y=0.06, width=0.8, height=0.08, color='white') | |
| # Column 3: Prediction (ensure same orientation as GT) | |
| plotter.subplot(0, 2) | |
| # Force surface-like rendering similar to ParaView | |
| actor = plotter.add_mesh(output_mesh, scalars="pred_pressure", clim=pressure_range, cmap="jet", | |
| show_edges=False, smooth_shading=False, show_scalar_bar=False, | |
| render_points_as_spheres=False, | |
| point_size=1.0, # Larger points if it's point cloud | |
| style='surface') # Force surface style | |
| plotter.add_scalar_bar(title='Pressure', title_font_size=18, label_font_size=18, | |
| position_x=0.1, position_y=0.06, width=0.8, height=0.08, color='white') | |
| # Open movie file with optimized settings | |
| plotter.open_movie(f"{output_name}.mp4", framerate=8, quality=5) # Lower settings for speed | |
| # Ultra-fast execution options: | |
| n_frames = 60 # Fewer frames for speed (30° steps) | |
| # Set initial camera position ONCE for all subplots | |
| for subplot_idx in range(3): | |
| plotter.subplot(0, subplot_idx) | |
| plotter.camera.elevation = -5 | |
| plotter.reset_camera() # Only call once at the beginning | |
| plotter.show(auto_close=False) | |
| print(f"Creating {n_frames} frames (speed optimized)...") | |
| for i in range(n_frames): | |
| angle = i * (360 / n_frames) # Calculate angle for full 360° rotation | |
| # Only change azimuth (fastest camera operation) | |
| for subplot_idx in range(3): | |
| plotter.subplot(0, subplot_idx) | |
| plotter.camera.azimuth = angle | |
| # NO reset_camera() here - this is the major slowdown! | |
| plotter.write_frame() | |
| # Progress indicator | |
| print(f"Frame {i+1}/{n_frames} ({(i+1)/n_frames*100:.0f}%)") | |
| print("Finalizing video...") | |
| plotter.close() | |
| print(f"✅ Fast video created: {output_name}.mp4") | |