Source code for viiapackage.shape_operations.viia_add_floor_openings

### ===================================================================================================================
###   Add openings to floors
### ===================================================================================================================
# Copyright ©VIIA 2024

### ===================================================================================================================
###   1. Import modules
### ===================================================================================================================

# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, List, Optional, Union
from copy import deepcopy

# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.shapes import Floor
from rhdhv_fem.shape_geometries import Node
from rhdhv_fem.general import Direction
from rhdhv_fem.fem_math import fem_flip_vector, fem_unit_vector

# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
    from viiapackage.viiaStatus import ViiaProject


### ===================================================================================================================
###   2. Function to add openings to floors
### ===================================================================================================================

[docs]def viia_add_floor_openings( project: ViiaProject, floor: Floor, opening_list: List[List], starting_point: Optional[Union[List[float], Node]] = None, direction: Optional[Union[List[float], Direction]] = None, flip: bool = False) -> Floor: """ Function to easily add openings to floors, based on measurements commonly specified in inspection data. This function is used by viia_add_openings, if a floor object is detected. Openings are specified by supplying a list of four values; distance to opening in given direction, length of the opening, distance perpendicular to that line and width of opening. Any next opening is defined continuing along the given direction. Input: - project (obj): VIIA project object containing collections of fem objects and project variables. - floor (obj): Object reference of floor on which the opening(s) are applied. - opening_list (list): List that contains the data for the openings. All measurements should be given in [m]. - starting_point (list of 2 floats): The starting point from which the measurements are taken. If not provided the first point of the floor definition is used. The z-coordinate of the point if given will be overwritten with the z-coordinate of the floor. Alternative input is providing a Node. It is not required that the starting point is on the floor, the opening points should. - direction (list of 2 floats): Direction from starting point that the dimensions are recorded in the inspection. If not provided the spanning direction of the floor is used for the direction of the dimension. Alternative input is providing a Direction. The direction is always only derived in the horizontal plane. - flip (bool): Select to flip the direction in which the openings are added to the shape. Default value False. Output: - The opening(s) are added to the floor. - The floor shape is returned. Example: The following example shows a floor on which two openings are added. First one starting on x=0 and y=1.8 relative to the first point of the floor and in the direction of the local x-axis. The first opening has a width of 1.1m and length of 2.3m. The second opening starts at x=4.1 and y=0.8 and has dimensions 0.5m x 0.5m. .. code-block:: python project.viia_add_floor_openings(floor=floor, opening_list=[[0, 1.1, 1.8, 2.3], [3, 0.5, 0.8, 0.5]] """ # Check if floor is flat if not floor.contour.is_horizontal(): raise ValueError("ERROR: The function to apply the openings on floors is designed only for horizontal floors.") # Check if direction is given and if is in plane if direction: if isinstance(direction, Direction): direction = deepcopy(direction.vector) direction[2] = 0 else: direction = floor.element_x_axis.vector # Flip the direction if required if flip: direction = fem_flip_vector(a=direction) # Create unit vector for direction direction = fem_unit_vector(vector=direction, precision=project.check_precision) # Check if starting point is given and is in plane if starting_point: if isinstance(starting_point, Node): starting_point = deepcopy(starting_point.coordinates) else: starting_point[2] = floor.contour.get_points()[0][2] else: starting_point = floor.contour.get_points()[0] x_tot = 0 # Create the openings in the list for opening in opening_list: # Check input if not isinstance(opening, list) or len(opening) != 4 or \ not all([isinstance(item, (float, int)) for item in opening]): raise ValueError( f"ERROR: Input for the openings in the list is incorrect. It should be a list of four values. " f"Provided was {opening}.") def rotate(x_r: float, y_r: float) -> List[float]: """ Function to calculate the x- and y-coordinate of the opening.""" return [ starting_point[0] + direction[0] * x_r - direction[1] * y_r, starting_point[1] + direction[1] * x_r + direction[0] * y_r, starting_point[2]] # Inputs distance_in_direction = opening[0] length = opening[1] distance_perpendicular = opening[2] width = opening[3] # Collect the opening points current_opening_points = [] # First opening point current_opening_points = [ rotate(x_r=x_tot + distance_in_direction, y_r=distance_perpendicular), rotate(x_r=x_tot + distance_in_direction + length, y_r=distance_perpendicular), rotate(x_r=x_tot + distance_in_direction + length, y_r=distance_perpendicular + width), rotate(x_r=x_tot + distance_in_direction, y_r=distance_perpendicular + width)] # Continue in the direction for any next opening x_tot += distance_in_direction + length # Add the opening to the floor floor.add_opening(polyline=current_opening_points) return floor
### =================================================================================================================== ### 3. End of script ### ===================================================================================================================