### ===================================================================================================================
### VIIA make movie
### ===================================================================================================================
# Copyright ©VIIA 2024
### ===================================================================================================================
### 1. Import modules
### ===================================================================================================================
# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, Tuple
import os
# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.fem_math import fem_greater
# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
from viiapackage.viiaStatus import ViiaProject
from viiapackage import installed_modules
# Import module numpy, check if module is installed
# This module is used for _viiaConvertWallToColumns
if 'cv2' in installed_modules:
import cv2
### ===================================================================================================================
### 2. Function to prepare for movies (find the minimum and maximum displacements XYZ)
### ===================================================================================================================
[docs]def viia_prepare_for_movies(project: ViiaProject, last_timestep: int) -> Tuple[float, float]:
"""
Function to prepare for movies.
Input:
- project (obj): Project object containing collections and of fem objects and project variables.
- last_timestep (int): The number of timesteps (including self-weight steps).
Output:
- Returns tuple of two floats, the minimum and maximum displacement for the movie.
"""
# Folder for movie pictures is sub-folder of analysis folder
movie_pictures_folder = project.current_analysis_folder / 'movie_pictures'
# Make sure the folder exists
movie_pictures_folder.mkdir(parents=True, exist_ok=True)
# Find limit displacements for movie
max_displ = -1000.0
min_displ = 0.0
if project.rhdhvDIANA.run_diana:
phase_nr = int(project.PhaseTimeLoadLabel.split(' ')[1]) - 1
output_step = f'Phase {phase_nr}, Extreme maximum up to Time-step {last_timestep}'
output_item_name = f'Displacements ({project.base_point.id})'
element_sets = []
for elementset in project.diana_settings.elementsets:
element_sets.append(elementset)
all_building_elements = []
for i, elementset in enumerate(element_sets):
for element in project.diana_settings.elementsets[elementset]['elements']:
all_building_elements.append(element)
all_building_nodes = []
for i, element in enumerate(all_building_elements):
for node in project.diana_settings.elements[element]['nodes']:
all_building_nodes.append(node)
for node_nr in all_building_nodes:
nod_x = project.rhdhvDIANA.resultData(
[project.LatestAnalyseName, project.output_max_name, output_step, output_item_name, 'TrDtXYZ'],
[node_nr])
try:
if fem_greater(float(nod_x[0][1]), max_displ):
max_displ = float(nod_x[0][1])
except IndexError:
pass
else:
max_displ = 0.01
# Return the minimum and maximum displacements
return min_displ, max_displ
### ===================================================================================================================
### 3. Function to create the movie, make sure ffmpeg is installed and added to Path
### ===================================================================================================================
[docs]def viia_movie_maker(project: ViiaProject):
"""
This function will create a movie from the movie pictures that have been created in the picture script.
Input:
- project (obj): Project object containing collections and of fem objects and project variables.
Output:
- A movie in mpeg format is created.
"""
# Check availability of cv2 module
if 'cv2' not in installed_modules:
raise ModuleNotFoundError("ERROR: The function viia_movie_maker needs third party cv2 module.")
work_dir = project.current_analysis_folder
movie_pictures_folder = work_dir / 'movie_pictures'
image_folder = movie_pictures_folder.as_posix() + '/'
os.makedirs(work_dir / 'movie_pictures')
movie_folder = work_dir / 'movie_pictures'
for file in work_dir.iterdir():
if file.suffix == '.png' and 'movie_time' in file.stem:
os.replace(file, movie_folder / file.name)
video_name = image_folder + 'displacements_video.avi'
images = [img for img in os.listdir(image_folder) if img.endswith(".png")]
frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape
video = cv2.VideoWriter(video_name, 0, 5, (width, height))
for image in images:
video.write(cv2.imread(os.path.join(image_folder, image)))
cv2.destroyAllWindows()
video.release()
### ===================================================================================================================
### 3. End of script
### ===================================================================================================================