Skip to content

Commit

Permalink
Add foundations.
Browse files Browse the repository at this point in the history
  • Loading branch information
iwatkot committed Feb 17, 2025
1 parent a7627b9 commit a335758
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,8 @@ You can also apply some advanced settings to the map generation process.<br>

- Water depth: Water depth value (in meters) will be subtracted from the DEM image, making the water deeper. The pixel value used for this is calculated based on the heightScale value for your map.

- Add foundations: If enabled the terrain under the buildings will be flattened to the average height of the building.

### Background terrain Advanced settings

- Generate background - if enabled, the obj files for the background terrain will be generated. You can turn it off if you already have those files or don't need them. By default, it's set to True.
Expand Down
1 change: 1 addition & 0 deletions data/fs25-texture-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"tags": { "building": true },
"width": 8,
"color": [130, 130, 130],
"info_layer": "buildings",
"procedural": ["PG_buildings"]
},
{
Expand Down
54 changes: 54 additions & 0 deletions maps4fs/generator/component/background.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import cv2
import numpy as np
from tqdm import tqdm

from maps4fs.generator.component.base.component_image import ImageComponent
from maps4fs.generator.component.base.component_mesh import MeshComponent
Expand Down Expand Up @@ -101,6 +102,56 @@ def process(self) -> None:
if self.map.background_settings.generate_water:
self.generate_water_resources_obj()

def create_foundations(self, dem_image: np.ndarray) -> np.ndarray:
"""Creates foundations for buildings based on the DEM data.
Arguments:
dem_image (np.ndarray): The DEM data as a numpy array.
Returns:
np.ndarray: The DEM data with the foundations added.
"""
buildings = self.get_infolayer_data(Parameters.TEXTURES, Parameters.BUILDINGS)
if not buildings:
self.logger.warning("Buildings data not found in textures info layer.")
return

self.logger.debug("Found %s buildings in textures info layer.", len(buildings))

for building in tqdm(buildings, desc="Creating foundations", unit="building"):
try:
fitted_building = self.fit_object_into_bounds(
polygon_points=building, angle=self.rotation
)
except ValueError as e:
self.logger.debug(
"Building could not be fitted into the map bounds with error: %s",
e,
)
continue

# 1. Read the pixel values from the DEM image.
# 2. Calculate the average pixel value of the building area.
# 3. Set the pixel values in the DEM to the average pixel value.

building_np = self.polygon_points_to_np(fitted_building)
mask = np.zeros(dem_image.shape, dtype=np.uint8)

try:
cv2.fillPoly(mask, [building_np], 255)
except Exception as e:
self.logger.debug("Could not create mask for building with error: %s", e)
continue

mean_value = cv2.mean(dem_image, mask=mask)[0]
mean_value = np.round(mean_value).astype(dem_image.dtype)
self.logger.info("Mean value of the building area: %s", mean_value)

# Set the pixel values in the DEM to the average pixel value.
dem_image[mask == 255] = mean_value

return dem_image

def make_copy(self, dem_path: str, dem_name: str) -> None:
"""Copies DEM data to additional DEM file.
Expand Down Expand Up @@ -198,6 +249,9 @@ def save_map_dem(self, dem_path: str, save_path: str | None = None) -> str:
self.logger.debug("Not resized DEM saved: %s", save_path)
return save_path

if self.map.dem_settings.add_foundations:
dem_data = self.create_foundations(dem_data)

output_size = self.map_size + 1

main_dem_path = self.game.dem_file_path(self.map_directory)
Expand Down
2 changes: 2 additions & 0 deletions maps4fs/generator/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Parameters:

FIELD = "field"
FIELDS = "fields"
BUILDINGS = "buildings"
TEXTURES = "textures"
FOREST = "forest"
ROADS_POLYLINES = "roads_polylines"
Expand Down Expand Up @@ -133,6 +134,7 @@ class DEMSettings(SettingsModel):
ceiling: int = 0
water_depth: int = 0
blur_radius: int = 3
add_foundations: bool = False


class BackgroundSettings(SettingsModel):
Expand Down
4 changes: 4 additions & 0 deletions webui/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ class Settings:
"ℹ️ **Units:** meters."
)

ADD_FOUNDATIONS = (
"If add foundations is enabled, the terrain under the buildings will be flattened."
)

# Background Settings

GENERATE_BACKGROUND = (
Expand Down

0 comments on commit a335758

Please sign in to comment.