### ===================================================================================================================
### viia_find_wall_openings
### ===================================================================================================================
# Copyright ©2026 Haskoning Nederland B.V.
# For use by VIIA
### ===================================================================================================================
### 1. Import modules
### ===================================================================================================================
# General imports
from typing import List
# References for functions and classes in the haskoning-datafusr-py-base package
from haskoning_datafusr_py_base.math import dot_product_vector, unit_vector, vector_between_points
# References for functions and classes in the haskoning-structural package
from haskoning_structural.shapes import Wall
from haskoning_structural.fem_shapes import fem_min_max_points
### ===================================================================================================================
### 2. Function to find the wall openings
### ===================================================================================================================
[docs]def viia_find_wall_openings(wall: Wall, direction_axis: List[float]):
"""
This function finds the openings of the wall with respect to the defined local x-axis. This axis generally goes from
left to right, seen from the inside (i.e. the direction of the outward wall vector). It returns a list that contains
the extreme x- and y-coordinates of wall openings.
Input:
- wall (obj): Object reference of wall shape.
- direction_axis (list of 3 floats): Vector of the direction in which the points of the openings are ordered.
Output:
- Returns a list with lists of 3 floats.
"""
# Initiate container for openings
opening_locations = []
# Find extreme x- and y-coordinates of openings
if wall.openings is not None:
for opening in wall.openings:
points = fem_min_max_points(collection=[opening])
# Find combination of x- and y-components of the extremes that are parallel to the localXAxis
p_min_min = [points['x-min'], points['y-min'], 0]
p_max_max = [points['x-max'], points['y-max'], 0]
p_min_max = [points['x-min'], points['y-max'], 0]
p_max_min = [points['x-max'], points['y-min'], 0]
uv1 = unit_vector(a=vector_between_points(point1=p_min_min, point2=p_max_max))
uv2 = unit_vector(a=vector_between_points(point1=p_min_max, point2=p_max_min))
# A dot product of 1 indicates parallel unit vectors with the same direction
# A dot product of -1 indicates parallel unit vectors with opposing direction
dp1 = dot_product_vector(a=uv1, b=direction_axis)
dp2 = dot_product_vector(a=uv2, b=direction_axis)
# Add opening in direction of localXAxis
if dp1 == 1:
opening_locations.append([p_min_min, p_max_max])
elif dp1 == -1:
opening_locations.append([p_max_max, p_min_min])
elif dp2 == 1:
opening_locations.append([p_min_max, p_max_min])
elif dp2 == -1:
opening_locations.append([p_max_min, p_min_max])
return opening_locations
### ===================================================================================================================
### 3. End of script
### ===================================================================================================================