Source code for viiapackage.tools.viia_create_roof

### ===================================================================================================================
###   CREATE ROOFS
### ===================================================================================================================
# 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.fem_math import fem_average_points, fem_unit_vector_2_points, fem_cross_product_vector, \
    fem_point_to_plane, fem_vector_2_points, fem_point_in_surface, fem_check_self_intersections, \
    fem_dot_product_vector, fem_point_on_contour_surface
from rhdhv_fem.shape_geometries import Polyline, Line
from rhdhv_fem.shapes import Shapes
from rhdhv_fem.groups import Layer

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


### ===================================================================================================================
###   2. Functions to create gable roof
### ===================================================================================================================

[docs]def viia_create_gable_roof( project: ViiaProject, layer: Union[Layer, str], wall_points: List, material_equivalent_plate: str, geometry_equivalent_plate: Union[int, float], height_ridge: Union[int, float], material_ridge: str = 'LIN-HOUT', geometry_ridge: str = None, material_wall_plate: str = 'LIN-HOUT', geometry_wall_plate: str = None) \ -> List[Shapes]: """ Function to create basic roof structure based on two wall plates and height of ridge. .. note:: The material of the collar tie can be modelled implicitly, or explicit. Select the appopriate material. Input: - project (obj): VIIA project object containing collections of fem objects and project variables. - layer (str or Layer): Name of the layer as a string, or the Layer object itself, to which the newly created roof should be added. - wall_points (list with lists with lists of 3 floats): A list which contains two lists with both two coordinates. The coordinates represent the start and endpoint of the wall plate. - material_equivalent_plate (str): Name of the material following VIIA naming convention. - geometry_equivalent_plate (int, float): Thickness of the equivalent plate. - material_ridge (str): Name of the material of the ridge following VIIA naming convention. Default value: 'LIN-HOUT'. - geometry_ridge (str): Name of the geometry of the ridge following VIIA naming convention. Default value: None. - material_wall_plate (str): Name of the material of the wall plates following VIIA naming convention. Default value: 'LIN-HOUT'. - geometry_wall_plate (str): Name of the geometry of the wall plates following VIIA naming convention. Default value: None. Output: - Creation of the shapes for gable roof (sheeting, optionally ridge beam, wall plates). A list with all the newly created shapes is returned. """ # Revert second pair of wall points if wall points are in opposite direction if fem_dot_product_vector( fem_unit_vector_2_points(point1=wall_points[0][0], point2=wall_points[0][1]), fem_unit_vector_2_points(point1=wall_points[1][0], point2=wall_points[1][1])) < 0: wall_points[1].reverse() # Get start and end point of ridge, as average of the wall points start_point_ridge = fem_average_points([wall_points[0][0], wall_points[1][0]]) end_point_ridge = fem_average_points([wall_points[0][1], wall_points[1][1]]) # Adjust height start_point_ridge[2] = height_ridge end_point_ridge[2] = height_ridge # Create line that forms the ridge ridge = project.create_line([start_point_ridge, end_point_ridge]) # Call base function return _viia_create_general_roof( project=project, layer=layer, wall_points=wall_points, material_equivalent_plate=material_equivalent_plate, geometry_equivalent_plate=geometry_equivalent_plate, ridge=ridge, material_ridge=material_ridge, geometry_ridge=geometry_ridge, material_wall_plate=material_wall_plate, geometry_wall_plate=geometry_wall_plate)
### =================================================================================================================== ### 3. Functions to create hip roof ### ===================================================================================================================
[docs]def viia_create_hip_roof( project: ViiaProject, layer: Union[Layer, str], wall_points: List, material_equivalent_plate: str, geometry_equivalent_plate: Union[int, float], ridge: Union[List[List[Union[int, float]]], 'Line'], material_ridge: str = 'LIN-HOUT', geometry_ridge: str = None, material_wall_plate: str = 'LIN-HOUT', geometry_wall_plate: str = None) -> List[Shapes]: """ Function to create basic roof structure based on two wall plates and height of ridge. Input: - project (obj): VIIA project object containing collections of fem objects and project variables. - layer (str or Layer): Name of the layer as a string, or the Layer object itself, to which the newly created roof should be added. - wall_points (list with lists with lists of 3 floats): A list which contains two lists with both two coordinates. The coordinates represent the start and endpoint of the wall plate - material_equivalent_plate (str): Name of the material following VIIA naming convention. - geometry_equivalent_plate (int, float): Thickness of the equivalent plate. - ridge (obj): Object reference of the line which represenst the ridge. Alternative (list with 2 lists of 3 floats): List with 2 coordinates of line, which represents the ridge. - material_ridge (str): Name of the material of the ridge following VIIA naming convention. Default value: 'LIN-HOUT'. - geometry_ridge (str): Name of the geometry of the ridge following VIIA naming convention. Default value: None. - material_wall_plate (str): Name of the material of the wall plates following VIIA naming convention. Default value: 'LIN-HOUT'. - geometry_wall_plate (str): Name of the geometry of the wall plates following VIIA naming convention. Default value: None. Output: - Creation of the shapes for hip roof (sheeting, optionally ridge beam, wall plates). A list of all newly created objects is returned. """ # If ridge is not yet a Line, make it a line if isinstance(ridge, Line): pass elif isinstance(ridge, list) and len(ridge) == 2: ridge = project.create_line([ridge[0], ridge[1]]) else: raise ValueError( "ERROR: Input for ridge for function viia_create_hip_roof is provided wrongly. Function not executed.") # Revert wall points in if ridge is in opposite direction if fem_dot_product_vector( fem_unit_vector_2_points(point1=wall_points[0][0], point2=wall_points[0][1]), ridge.get_direction().vector) < 0: wall_points[0].reverse() if fem_dot_product_vector( fem_unit_vector_2_points(point1=wall_points[1][0], point2=wall_points[1][1]), ridge.get_direction().vector) < 0: wall_points[1].reverse() # Call base function return _viia_create_general_roof( project=project, layer=layer, wall_points=wall_points, material_equivalent_plate=material_equivalent_plate, geometry_equivalent_plate=geometry_equivalent_plate, ridge=ridge, material_ridge=material_ridge, geometry_ridge=geometry_ridge, material_wall_plate=material_wall_plate, geometry_wall_plate=geometry_wall_plate)
### =================================================================================================================== ### 4. Base function for creating roofs ### ===================================================================================================================
[docs]def _viia_create_general_roof( project: ViiaProject, layer: Union[Layer, str], wall_points: List, material_equivalent_plate: str, geometry_equivalent_plate: Union[int, float], ridge: Union['Line', 'Polyline'], material_ridge: Optional[str] = None, geometry_ridge: Optional[str] = None, material_wall_plate: Optional[str] = None, geometry_wall_plate: Optional[str] = None) -> List[Shapes]: """ Function to create basic roof structure based on two wall plates and height of ridge. Input: - project (obj): VIIA project object containing collections of fem objects and project variables. - layer (str or Layer): Name of the layer as a string, or the Layer object itself, to which the newly created roof should be added. - wall_points (list with lists with lists of 3 floats): A list which contains two lists with both two coordinates. The coordinates represent the start and endpoint of the wall plate - material_equivalent_plate (str): String describing the name of the material of the equivalent roof plates, following VIIA naming convention. - geometry_equivalent_plate (str): Thickness of the equivalent plate. - ridge (obj): Object reference of the line which represents the ridge. Alternative (list with 2 lists of 3 floats): List with 2 coordinates of line, which represents the ridge. - material_ridge (str): Name of the material of the ridge following VIIA naming convention. Default value: 'LIN-HOUT'. - geometry_ridge (str): Name of the geometry of the ridge following VIIA naming convention. Default value: None. - material_wall_plate (str): Name of the material of the wall plates following VIIA naming convention. Default value: 'LIN-HOUT'. - geometry_wall_plate (str): Name of the geometry of the wall plates following VIIA naming convention. Default value: None. Output: - Creation of the shapes for the roof (sheeting, optionally ridge beam, wall plates). A list with all the newly created shapes is returned. """ # Wall points should already be ordered, nevertheless check again # Revert second pair of wall points if wall points are in opposite direction if fem_dot_product_vector( fem_unit_vector_2_points(point1=wall_points[0][0], point2=wall_points[0][1]), fem_unit_vector_2_points(point1=wall_points[1][0], point2=wall_points[1][1])) < 0: wall_points[1].reverse() start_point_1 = wall_points[0][0] end_point_1 = wall_points[0][1] start_point_2 = wall_points[1][0] end_point_2 = wall_points[1][1] start_point_ridge = ridge.get_startnode().coordinates end_point_ridge = ridge.get_endnode().coordinates # Make ridge beam if properties are provided ridge_beam = None if material_ridge is not None and geometry_ridge is not None: ridge_beam = project.viia_create_beam( name=layer, material=material_ridge, geometry=geometry_ridge, points=ridge.get_points(), is_roof_beam=True) # Make wall plates if properties are provided wall_plate_1 = None wall_plate_2 = None if material_wall_plate is not None and geometry_wall_plate is not None: wall_plate_1 = project.viia_create_beam( name=layer, points=[start_point_1, end_point_1], material=material_wall_plate, geometry=geometry_wall_plate, is_roof_beam=True) wall_plate_2 = project.viia_create_beam( name=layer, points=[start_point_2, end_point_2], material=material_wall_plate, geometry=geometry_wall_plate, is_roof_beam=True) # Make roof plates roof_1 = project.viia_create_roof( name=layer, material=material_equivalent_plate, geometry=geometry_equivalent_plate, points=[[start_point_1, start_point_ridge, end_point_ridge, end_point_1]]) roof_2 = project.viia_create_roof( name=layer, material=material_equivalent_plate, geometry=geometry_equivalent_plate, points=[[start_point_2, start_point_ridge, end_point_ridge, end_point_2]]) # Update local element axes ridge_direction = fem_vector_2_points(start_point_ridge, end_point_ridge) roof_1.update_local_x_axis(local_x_axis=fem_cross_product_vector(roof_1.normal_vector(), ridge_direction)) roof_2.update_local_x_axis(local_x_axis=fem_cross_product_vector(roof_2.normal_vector(), ridge_direction)) # Create horizontal plane of wall points horizontal_wall_points = deepcopy(wall_points[0]) + deepcopy(wall_points[1]) for i in range(len(horizontal_wall_points)): horizontal_wall_points[i][2] = 0 # Revert last two points if the plane is self intersecting if fem_check_self_intersections(horizontal_wall_points): horizontal_wall_points.append(horizontal_wall_points[2]) horizontal_wall_points.pop(2) # Project start and end point ridge to horizontal plane projected_start_point = fem_point_to_plane(start_point_ridge, horizontal_wall_points, direction=[0, 0, 1]) projected_end_point = fem_point_to_plane(end_point_ridge, horizontal_wall_points, direction=[0, 0, 1]) roof_3 = None roof_4 = None wall_plate_3 = None wall_plate_4 = None # If projected point within surface and not on contour, create roof plate if fem_point_in_surface(projected_start_point, horizontal_wall_points) and not \ fem_point_on_contour_surface(projected_start_point, horizontal_wall_points): roof_3 = project.viia_create_roof( name=layer, material=material_equivalent_plate, geometry=geometry_equivalent_plate, points=[[start_point_1, start_point_2, start_point_ridge]]) wall_direction = fem_vector_2_points(start_point_1, start_point_2) roof_3.update_local_x_axis(fem_cross_product_vector(roof_3.normal_vector(), wall_direction)) # Also create wall plate if properties are provided if material_wall_plate is not None and geometry_wall_plate is not None: wall_plate_3 = project.viia_create_beam( name=layer, material=material_wall_plate, geometry=geometry_wall_plate, points=[start_point_1, start_point_2], is_roof_beam=True) # If projected point within surface and not on contour, create roof plate if fem_point_in_surface(projected_end_point, horizontal_wall_points) and not \ fem_point_on_contour_surface(projected_end_point, horizontal_wall_points): roof_4 = project.viia_create_roof( name=layer, material=material_equivalent_plate, geometry=geometry_equivalent_plate, points=[[end_point_1, end_point_2, end_point_ridge]]) wall_direction = fem_vector_2_points(end_point_1, end_point_2) roof_4.update_local_x_axis(fem_cross_product_vector(roof_4.normal_vector(), wall_direction)) # Also create wall plate if properties are provided if material_wall_plate is not None and geometry_wall_plate is not None: wall_plate_4 = project.viia_create_beam( name=layer, material=material_wall_plate, geometry=geometry_wall_plate, points=[end_point_1, end_point_2], is_roof_beam=True) # Return created shapes return [item for item in [ ridge_beam, wall_plate_1, wall_plate_2, wall_plate_3, wall_plate_4, roof_1, roof_2, roof_3, roof_4] if item]
### =================================================================================================================== ### 5. End of script ### ===================================================================================================================