From c5cde4ae7f8fca6524cca2ab87dc629e28f95dbf Mon Sep 17 00:00:00 2001 From: LuukBoot <121462516+LuukBoot@users.noreply.github.com> Date: Mon, 26 Jun 2023 11:33:03 +0200 Subject: [PATCH 1/2] Updated to editor --- README.md | 2 +- app/building/controller.py => app.py | 62 ++- app/__init__.py | 22 - app/building/__init__.py | 15 - app/building/parametrization.py | 67 --- ...s_and_prices.py => materials_and_prices.py | 74 ++-- app/building/model.py => model.py | 390 +++++++++--------- viktor.config.toml | 2 +- 8 files changed, 292 insertions(+), 342 deletions(-) rename app/building/controller.py => app.py (71%) delete mode 100644 app/__init__.py delete mode 100644 app/building/__init__.py delete mode 100644 app/building/parametrization.py rename app/building/materials_and_prices.py => materials_and_prices.py (97%) rename app/building/model.py => model.py (92%) diff --git a/README.md b/README.md index 564e7e2..fcbd9ab 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,6 @@ This is a sample app demonstrates the use of parametric design to build a simple Using this app you can parametrically generate a building structure. For each generated building structure, the environmental impact is shown as the Shadow Cost over the lifecycle of the building structure. # App structure -This is an tree app. +This is an editor app. diff --git a/app/building/controller.py b/app.py similarity index 71% rename from app/building/controller.py rename to app.py index 7929c9c..0a5f059 100644 --- a/app/building/controller.py +++ b/app.py @@ -13,6 +13,8 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ +from viktor.parametrization import Parametrization, NumberField, OptionField + from munch import Munch from viktor.core import ViktorController from viktor.geometry import Group @@ -20,10 +22,62 @@ from viktor.views import DataItem from viktor.views import GeometryAndDataResult from viktor.views import GeometryAndDataView -from .model import calculate_prices -from .model import create_building_geometries -from .model import create_ground_surface -from .parametrization import BuildingParametrization +from model import calculate_prices +from model import create_building_geometries +from model import create_ground_surface + +_material_options = [ + "Prefab Concrete", + "Steel Composite", + "Cross-Laminated-Timber", + "CLT Composite", +] + + +class BuildingParametrization(Parametrization): + """Defines the input fields in left-side of the web UI in the Building entity (Editor).""" + width = NumberField( + "Building width", + suffix="m", + default=20, + min=10, + max=30, + num_decimals=1, + variant="slider", + flex=100, + ) + length = NumberField( + "Building Length", + suffix="m", + default=30, + min=20, + max=40, + num_decimals=1, + variant="slider", + flex=100, + ) + floor_height = NumberField( + "Floor Height", + suffix="m", + default=3, + step=0.1, + min=2.5, + max=4.0, + num_decimals=1, + variant="slider", + flex=100, + ) + floors = NumberField( + "Floors", default=3, min=1, max=10, num_decimals=1, variant="slider", flex=100 + ) + material = OptionField( + "Construction Material", + options=_material_options, + default="Prefab Concrete", + variant="radio", + flex=100) + + class BuildingController(ViktorController): diff --git a/app/__init__.py b/app/__init__.py deleted file mode 100644 index b6ca4d5..0000000 --- a/app/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -"""Copyright (c) 2021 VIKTOR B.V. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. - -VIKTOR B.V. PROVIDES THIS SOFTWARE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" -from .building.controller import BuildingController as Building - -from viktor import InitialEntity - -initial_entities = [ - InitialEntity('Building', name='Parametric Building Structure') -] diff --git a/app/building/__init__.py b/app/building/__init__.py deleted file mode 100644 index 6e597ba..0000000 --- a/app/building/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -"""Copyright (c) 2021 VIKTOR B.V. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. - -VIKTOR B.V. PROVIDES THIS SOFTWARE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" diff --git a/app/building/parametrization.py b/app/building/parametrization.py deleted file mode 100644 index b5e0f7d..0000000 --- a/app/building/parametrization.py +++ /dev/null @@ -1,67 +0,0 @@ -"""Copyright (c) 2021 VIKTOR B.V. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. - -VIKTOR B.V. PROVIDES THIS SOFTWARE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" -from viktor.parametrization import Parametrization, NumberField, OptionField - -_material_options = [ - "Prefab Concrete", - "Steel Composite", - "Cross-Laminated-Timber", - "CLT Composite", -] - - -class BuildingParametrization(Parametrization): - """Defines the input fields in left-side of the web UI in the Building entity (Editor).""" - width = NumberField( - "Building width", - suffix="m", - default=20, - min=10, - max=30, - num_decimals=1, - variant="slider", - flex=100, - ) - length = NumberField( - "Building Length", - suffix="m", - default=30, - min=20, - max=40, - num_decimals=1, - variant="slider", - flex=100, - ) - floor_height = NumberField( - "Floor Height", - suffix="m", - default=3, - step=0.1, - min=2.5, - max=4.0, - num_decimals=1, - variant="slider", - flex=100, - ) - floors = NumberField( - "Floors", default=3, min=1, max=10, num_decimals=1, variant="slider", flex=100 - ) - material = OptionField( - "Construction Material", - options=_material_options, - default="Prefab Concrete", - variant="radio", - flex=100) diff --git a/app/building/materials_and_prices.py b/materials_and_prices.py similarity index 97% rename from app/building/materials_and_prices.py rename to materials_and_prices.py index 7d2b381..a754f75 100644 --- a/app/building/materials_and_prices.py +++ b/materials_and_prices.py @@ -1,37 +1,37 @@ -"""Copyright (c) 2021 VIKTOR B.V. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. - -VIKTOR B.V. PROVIDES THIS SOFTWARE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" -from viktor.core import Color -from viktor.geometry import Material - -SHADOW_PRICE_SLAB_PER_M2 = { - "Prefab Concrete": 12.8, - "Cross-Laminated-Timber": 0.9, - "Steel Composite": 10.2, -} -SHADOW_PRICE_COLUMN_PER_M = { - "Prefab Concrete": 17.1, - "Cross-Laminated-Timber": 0.7, - "Steel Composite": 9.0, -} -SHADOW_PRICE_CORE_PER_M2 = { - "Prefab Concrete": 6.9, - "Cross-Laminated-Timber": 0.9 -} - -PREFAB_CONCRETE = Material("Prefab Concrete", color=Color(220, 220, 220)) -TIMBER = Material("Cross-Laminated-Timber", color=Color(250, 200, 150)) -STEEL = Material("Steel Composite", color=Color(100, 100, 100)) -GROUND = Material("ground green", color=Color(200, 250, 155)) +"""Copyright (c) 2021 VIKTOR B.V. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the +Software. + +VIKTOR B.V. PROVIDES THIS SOFTWARE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +""" +from viktor.core import Color +from viktor.geometry import Material + +SHADOW_PRICE_SLAB_PER_M2 = { + "Prefab Concrete": 12.8, + "Cross-Laminated-Timber": 0.9, + "Steel Composite": 10.2, +} +SHADOW_PRICE_COLUMN_PER_M = { + "Prefab Concrete": 17.1, + "Cross-Laminated-Timber": 0.7, + "Steel Composite": 9.0, +} +SHADOW_PRICE_CORE_PER_M2 = { + "Prefab Concrete": 6.9, + "Cross-Laminated-Timber": 0.9 +} + +PREFAB_CONCRETE = Material("Prefab Concrete", color=Color(220, 220, 220)) +TIMBER = Material("Cross-Laminated-Timber", color=Color(250, 200, 150)) +STEEL = Material("Steel Composite", color=Color(100, 100, 100)) +GROUND = Material("ground green", color=Color(200, 250, 155)) diff --git a/app/building/model.py b/model.py similarity index 92% rename from app/building/model.py rename to model.py index 505626a..e25e986 100644 --- a/app/building/model.py +++ b/model.py @@ -1,195 +1,195 @@ -"""Copyright (c) 2021 VIKTOR B.V. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. - -VIKTOR B.V. PROVIDES THIS SOFTWARE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" -from typing import Dict -from typing import List -from typing import Tuple - -import numpy as np -from munch import Munch - -from viktor.core import UserError -from viktor.geometry import Line -from viktor.geometry import Point -from viktor.geometry import Polygon -from viktor.geometry import RectangularExtrusion - -from .materials_and_prices import GROUND -from .materials_and_prices import PREFAB_CONCRETE -from .materials_and_prices import SHADOW_PRICE_COLUMN_PER_M -from .materials_and_prices import SHADOW_PRICE_CORE_PER_M2 -from .materials_and_prices import SHADOW_PRICE_SLAB_PER_M2 -from .materials_and_prices import STEEL -from .materials_and_prices import TIMBER - - -def determine_materials(selected_material): - """Determine colors of each part based on material parameter""" - if selected_material == "Prefab Concrete": - slab_material = PREFAB_CONCRETE - column_material = PREFAB_CONCRETE - core_material = PREFAB_CONCRETE - column_span = 7.0 - elif selected_material == "Cross-Laminated-Timber": - slab_material = TIMBER - column_material = TIMBER - core_material = TIMBER - column_span = 6.0 - elif selected_material == "Steel Composite": - slab_material = STEEL - column_material = STEEL - core_material = PREFAB_CONCRETE - column_span = 8.0 - elif selected_material == "CLT Composite": - slab_material = PREFAB_CONCRETE - column_material = TIMBER - core_material = PREFAB_CONCRETE - column_span = 5.0 - else: - raise UserError("Unknown material selected") - - return slab_material, column_material, core_material, column_span - - -def create_building_geometries(params: Munch) -> Tuple[ - List[RectangularExtrusion], - List[RectangularExtrusion], - RectangularExtrusion, -]: - """Creates the building geometry, including the slabs, columns and core""" - columns = [] - column_offset = 0.5 - slab_thickness = 0.3 - slab_material, column_material, core_material, column_span = determine_materials( - params.material - ) - - column_positions_width = np.linspace( - start=-0.5 * params.width + column_offset, - stop=0.5 * params.width - column_offset, - num=round(params.width / column_span + 1), - ) - - column_positions_length = np.linspace( - start=-0.5 * params.length + column_offset, - stop=0.5 * params.length - column_offset, - num=round(params.length / column_span + 1), - ) - - for i in range(params.floors): - for width_position in column_positions_width: - for length_position in column_positions_length: - point_start = Point( - width_position, - length_position, - i * params.floor_height + slab_thickness, - ) - point_end = Point( - width_position, length_position, (i + 1) * params.floor_height - ) - extrusion_midline = Line(point_start, point_end) - column = RectangularExtrusion( - width=0.5, - height=0.5, - line=extrusion_midline, - material=column_material, - ) - columns.append(column) - - # Make slabs - slabs = [] - for i in range(params.floors + 1): - point_start = Point(0, 0, i * params.floor_height) - point_end = Point(0, 0, i * params.floor_height + slab_thickness) - extrusion_midline = Line(point_start, point_end) - slab = RectangularExtrusion( - width=params.width, - height=params.length, - line=extrusion_midline, - material=slab_material, - ) - slabs.append(slab) - - # Make structural core - core_width, core_length = 6, 8 - point_start = Point(0, 0, slab_thickness) - point_end = Point(0, 0, params.floors * params.floor_height) - extrusion_midline = Line(point_start, point_end) - core = RectangularExtrusion( - width=core_width, - height=core_length, - line=extrusion_midline, - material=core_material, - ) - return slabs, columns, core - - -def create_ground_surface() -> Polygon: - """Creates the ground surface""" - # Make ground surface - x_centre, y_centre = 0, 0 # centre of the circle - radius = 35 # radius of circle - points_on_circle = [] - amount_of_points = 100 - - for angle in np.linspace(0, 2 * np.pi, amount_of_points, endpoint=False): - point = Point(x_centre + np.sin(angle) * radius, y_centre + np.cos(angle) * radius) - points_on_circle.append(point) - - ground_surface = Polygon(points_on_circle, material=GROUND) - return ground_surface - - -def calculate_prices( - slabs: List[RectangularExtrusion], - columns: List[RectangularExtrusion], - core: RectangularExtrusion, -) -> Dict[str, float]: - """Creates a dict containing the shadow prices (MKI)""" - # Determine shadow cost of slabs - slab_area_total = 0 - shadow_price_slabs = 0 - - for slab in slabs: - shadow_price_slabs += ( - slab.cross_sectional_area * SHADOW_PRICE_SLAB_PER_M2[slab.material.name] - ) - slab_area_total += slab.cross_sectional_area - - # Determine shadow cost of columns - shadow_price_columns = 0 - for column in columns: - shadow_price_columns += ( - column.length * SHADOW_PRICE_COLUMN_PER_M[column.material.name] - ) - - # Determine shadow cost of core - core_surface_area = (core.width * 2 + core.height * 2) * core.length - shadow_price_core = core_surface_area * SHADOW_PRICE_CORE_PER_M2[core.material.name] - - # Determine total shadow price - shadow_price = shadow_price_slabs + shadow_price_columns + shadow_price_core - shadow_price_per_m2_total = shadow_price / slab_area_total - - # Present data - prices_data = { - "Shadow Price (MKI)": shadow_price, - "Shadow Price per m2": shadow_price_per_m2_total, - "Shadow Price Slabs": shadow_price_slabs, - "Shadow Price Columns": shadow_price_columns, - "Shadow Price Core": shadow_price_core, - } - - return prices_data +"""Copyright (c) 2021 VIKTOR B.V. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the +Software. + +VIKTOR B.V. PROVIDES THIS SOFTWARE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +""" +from typing import Dict +from typing import List +from typing import Tuple + +import numpy as np +from munch import Munch + +from viktor.core import UserError +from viktor.geometry import Line +from viktor.geometry import Point +from viktor.geometry import Polygon +from viktor.geometry import RectangularExtrusion + +from materials_and_prices import GROUND +from materials_and_prices import PREFAB_CONCRETE +from materials_and_prices import SHADOW_PRICE_COLUMN_PER_M +from materials_and_prices import SHADOW_PRICE_CORE_PER_M2 +from materials_and_prices import SHADOW_PRICE_SLAB_PER_M2 +from materials_and_prices import STEEL +from materials_and_prices import TIMBER + + +def determine_materials(selected_material): + """Determine colors of each part based on material parameter""" + if selected_material == "Prefab Concrete": + slab_material = PREFAB_CONCRETE + column_material = PREFAB_CONCRETE + core_material = PREFAB_CONCRETE + column_span = 7.0 + elif selected_material == "Cross-Laminated-Timber": + slab_material = TIMBER + column_material = TIMBER + core_material = TIMBER + column_span = 6.0 + elif selected_material == "Steel Composite": + slab_material = STEEL + column_material = STEEL + core_material = PREFAB_CONCRETE + column_span = 8.0 + elif selected_material == "CLT Composite": + slab_material = PREFAB_CONCRETE + column_material = TIMBER + core_material = PREFAB_CONCRETE + column_span = 5.0 + else: + raise UserError("Unknown material selected") + + return slab_material, column_material, core_material, column_span + + +def create_building_geometries(params: Munch) -> Tuple[ + List[RectangularExtrusion], + List[RectangularExtrusion], + RectangularExtrusion, +]: + """Creates the building geometry, including the slabs, columns and core""" + columns = [] + column_offset = 0.5 + slab_thickness = 0.3 + slab_material, column_material, core_material, column_span = determine_materials( + params.material + ) + + column_positions_width = np.linspace( + start=-0.5 * params.width + column_offset, + stop=0.5 * params.width - column_offset, + num=round(params.width / column_span + 1), + ) + + column_positions_length = np.linspace( + start=-0.5 * params.length + column_offset, + stop=0.5 * params.length - column_offset, + num=round(params.length / column_span + 1), + ) + + for i in range(params.floors): + for width_position in column_positions_width: + for length_position in column_positions_length: + point_start = Point( + width_position, + length_position, + i * params.floor_height + slab_thickness, + ) + point_end = Point( + width_position, length_position, (i + 1) * params.floor_height + ) + extrusion_midline = Line(point_start, point_end) + column = RectangularExtrusion( + width=0.5, + height=0.5, + line=extrusion_midline, + material=column_material, + ) + columns.append(column) + + # Make slabs + slabs = [] + for i in range(params.floors + 1): + point_start = Point(0, 0, i * params.floor_height) + point_end = Point(0, 0, i * params.floor_height + slab_thickness) + extrusion_midline = Line(point_start, point_end) + slab = RectangularExtrusion( + width=params.width, + height=params.length, + line=extrusion_midline, + material=slab_material, + ) + slabs.append(slab) + + # Make structural core + core_width, core_length = 6, 8 + point_start = Point(0, 0, slab_thickness) + point_end = Point(0, 0, params.floors * params.floor_height) + extrusion_midline = Line(point_start, point_end) + core = RectangularExtrusion( + width=core_width, + height=core_length, + line=extrusion_midline, + material=core_material, + ) + return slabs, columns, core + + +def create_ground_surface() -> Polygon: + """Creates the ground surface""" + # Make ground surface + x_centre, y_centre = 0, 0 # centre of the circle + radius = 35 # radius of circle + points_on_circle = [] + amount_of_points = 100 + + for angle in np.linspace(0, 2 * np.pi, amount_of_points, endpoint=False): + point = Point(x_centre + np.sin(angle) * radius, y_centre + np.cos(angle) * radius) + points_on_circle.append(point) + + ground_surface = Polygon(points_on_circle, material=GROUND) + return ground_surface + + +def calculate_prices( + slabs: List[RectangularExtrusion], + columns: List[RectangularExtrusion], + core: RectangularExtrusion, +) -> Dict[str, float]: + """Creates a dict containing the shadow prices (MKI)""" + # Determine shadow cost of slabs + slab_area_total = 0 + shadow_price_slabs = 0 + + for slab in slabs: + shadow_price_slabs += ( + slab.cross_sectional_area * SHADOW_PRICE_SLAB_PER_M2[slab.material.name] + ) + slab_area_total += slab.cross_sectional_area + + # Determine shadow cost of columns + shadow_price_columns = 0 + for column in columns: + shadow_price_columns += ( + column.length * SHADOW_PRICE_COLUMN_PER_M[column.material.name] + ) + + # Determine shadow cost of core + core_surface_area = (core.width * 2 + core.height * 2) * core.length + shadow_price_core = core_surface_area * SHADOW_PRICE_CORE_PER_M2[core.material.name] + + # Determine total shadow price + shadow_price = shadow_price_slabs + shadow_price_columns + shadow_price_core + shadow_price_per_m2_total = shadow_price / slab_area_total + + # Present data + prices_data = { + "Shadow Price (MKI)": shadow_price, + "Shadow Price per m2": shadow_price_per_m2_total, + "Shadow Price Slabs": shadow_price_slabs, + "Shadow Price Columns": shadow_price_columns, + "Shadow Price Core": shadow_price_core, + } + + return prices_data diff --git a/viktor.config.toml b/viktor.config.toml index 9bb21b8..d617081 100644 --- a/viktor.config.toml +++ b/viktor.config.toml @@ -1,2 +1,2 @@ welcome_text = "manifest\\welcome_text.txt" -app_type = "tree" +app_type = "editor" From 86a509bfcf5c19028fa60abe4e0eb8572f0ed97f Mon Sep 17 00:00:00 2001 From: LuukBoot <121462516+LuukBoot@users.noreply.github.com> Date: Mon, 26 Jun 2023 16:41:03 +0200 Subject: [PATCH 2/2] Updated what is next page --- app.py | 11 ++++++ next_step.html | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 next_step.html diff --git a/app.py b/app.py index 0a5f059..39ad812 100644 --- a/app.py +++ b/app.py @@ -15,6 +15,7 @@ """ from viktor.parametrization import Parametrization, NumberField, OptionField +from pathlib import Path from munch import Munch from viktor.core import ViktorController from viktor.geometry import Group @@ -22,6 +23,8 @@ from viktor.views import DataItem from viktor.views import GeometryAndDataResult from viktor.views import GeometryAndDataView +from viktor.views import WebView +from viktor.views import WebResult from model import calculate_prices from model import create_building_geometries from model import create_ground_surface @@ -133,3 +136,11 @@ def visualize(self, params: Munch, **kwargs) -> GeometryAndDataResult: return GeometryAndDataResult( Group([ground_surface, core, *slabs, *columns]), data ) + + @WebView("What's next?", duration_guess=1) + def whats_next(self, params, **kwargs): + """Initiates the process of rendering the "What's next" tab.""" + html_path = Path(__file__).parent / "next_step.html" + with html_path.open(encoding="utf-8") as _file: + html_string = _file.read() + return WebResult(html=html_string) diff --git a/next_step.html b/next_step.html new file mode 100644 index 0000000..ca54c37 --- /dev/null +++ b/next_step.html @@ -0,0 +1,90 @@ + + +
++ Do you want to explore more public VIKTOR apps? +
+ Explore apps ++ Do you want to build your own VIKTOR app? +
+ Get started! ++ Curious how this app was built? Go check out the repository: +
+ Github repository +