### ===================================================================================================================
### 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
### ===================================================================================================================