maps4fs 1.2.3__py3-none-any.whl → 1.2.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- maps4fs/generator/background.py +177 -15
- maps4fs/generator/component.py +8 -2
- maps4fs/generator/texture.py +33 -9
- {maps4fs-1.2.3.dist-info → maps4fs-1.2.5.dist-info}/METADATA +9 -1
- {maps4fs-1.2.3.dist-info → maps4fs-1.2.5.dist-info}/RECORD +8 -8
- {maps4fs-1.2.3.dist-info → maps4fs-1.2.5.dist-info}/LICENSE.md +0 -0
- {maps4fs-1.2.3.dist-info → maps4fs-1.2.5.dist-info}/WHEEL +0 -0
- {maps4fs-1.2.3.dist-info → maps4fs-1.2.5.dist-info}/top_level.txt +0 -0
maps4fs/generator/background.py
CHANGED
@@ -3,8 +3,10 @@ around the map."""
|
|
3
3
|
|
4
4
|
from __future__ import annotations
|
5
5
|
|
6
|
+
import json
|
6
7
|
import os
|
7
8
|
import shutil
|
9
|
+
from copy import deepcopy
|
8
10
|
|
9
11
|
import cv2
|
10
12
|
import numpy as np
|
@@ -17,6 +19,7 @@ from maps4fs.generator.dem import (
|
|
17
19
|
DEFAULT_PLATEAU,
|
18
20
|
DEM,
|
19
21
|
)
|
22
|
+
from maps4fs.generator.texture import Texture
|
20
23
|
|
21
24
|
DEFAULT_DISTANCE = 2048
|
22
25
|
RESIZE_FACTOR = 1 / 8
|
@@ -25,6 +28,7 @@ FULL_PREVIEW_NAME = "PREVIEW"
|
|
25
28
|
ELEMENTS = [FULL_NAME, FULL_PREVIEW_NAME]
|
26
29
|
|
27
30
|
|
31
|
+
# pylint: disable=R0902
|
28
32
|
class Background(Component):
|
29
33
|
"""Component for creating 3D obj files based on DEM data around the map.
|
30
34
|
|
@@ -43,7 +47,9 @@ class Background(Component):
|
|
43
47
|
def preprocess(self) -> None:
|
44
48
|
"""Registers the DEMs for the background terrain."""
|
45
49
|
self.light_version = self.kwargs.get("light_version", False)
|
50
|
+
self.water_depth = self.kwargs.get("water_depth", 0)
|
46
51
|
self.stl_preview_path: str | None = None
|
52
|
+
self.water_resources_path: str | None = None
|
47
53
|
|
48
54
|
if self.rotation:
|
49
55
|
self.logger.debug("Rotation is enabled: %s.", self.rotation)
|
@@ -51,22 +57,29 @@ class Background(Component):
|
|
51
57
|
else:
|
52
58
|
output_size_multiplier = 1
|
53
59
|
|
54
|
-
background_size = self.map_size + DEFAULT_DISTANCE * 2
|
55
|
-
rotated_size = int(background_size * output_size_multiplier)
|
60
|
+
self.background_size = self.map_size + DEFAULT_DISTANCE * 2
|
61
|
+
self.rotated_size = int(self.background_size * output_size_multiplier)
|
56
62
|
|
57
63
|
self.background_directory = os.path.join(self.map_directory, "background")
|
64
|
+
self.water_directory = os.path.join(self.map_directory, "water")
|
58
65
|
os.makedirs(self.background_directory, exist_ok=True)
|
66
|
+
os.makedirs(self.water_directory, exist_ok=True)
|
59
67
|
|
60
68
|
autoprocesses = [self.kwargs.get("auto_process", False), False]
|
69
|
+
self.output_paths = [
|
70
|
+
os.path.join(self.background_directory, f"{name}.png") for name in ELEMENTS
|
71
|
+
]
|
72
|
+
self.not_substracted_path = os.path.join(self.background_directory, "not_substracted.png")
|
73
|
+
|
61
74
|
dems = []
|
62
75
|
|
63
|
-
for name, autoprocess in zip(ELEMENTS, autoprocesses):
|
76
|
+
for name, autoprocess, output_path in zip(ELEMENTS, autoprocesses, self.output_paths):
|
64
77
|
dem = DEM(
|
65
78
|
self.game,
|
66
79
|
self.map,
|
67
80
|
self.coordinates,
|
68
|
-
background_size,
|
69
|
-
rotated_size,
|
81
|
+
self.background_size,
|
82
|
+
self.rotated_size,
|
70
83
|
self.rotation,
|
71
84
|
self.map_directory,
|
72
85
|
self.logger,
|
@@ -77,8 +90,8 @@ class Background(Component):
|
|
77
90
|
)
|
78
91
|
dem.preprocess()
|
79
92
|
dem.is_preview = self.is_preview(name) # type: ignore
|
80
|
-
dem.set_output_resolution((rotated_size, rotated_size))
|
81
|
-
dem.set_dem_path(
|
93
|
+
dem.set_output_resolution((self.rotated_size, self.rotated_size))
|
94
|
+
dem.set_dem_path(output_path)
|
82
95
|
dems.append(dem)
|
83
96
|
|
84
97
|
self.dems = dems
|
@@ -98,8 +111,17 @@ class Background(Component):
|
|
98
111
|
"""Launches the component processing. Iterates over all tiles and processes them
|
99
112
|
as a result the DEM files will be saved, then based on them the obj files will be
|
100
113
|
generated."""
|
114
|
+
self.create_background_textures()
|
115
|
+
|
101
116
|
for dem in self.dems:
|
102
117
|
dem.process()
|
118
|
+
if not dem.is_preview: # type: ignore
|
119
|
+
shutil.copyfile(dem.dem_path, self.not_substracted_path)
|
120
|
+
|
121
|
+
if self.water_depth:
|
122
|
+
self.subtraction()
|
123
|
+
|
124
|
+
for dem in self.dems:
|
103
125
|
if not dem.is_preview: # type: ignore
|
104
126
|
cutted_dem_path = self.cutout(dem.dem_path)
|
105
127
|
if self.game.additional_dem_name is not None:
|
@@ -107,6 +129,7 @@ class Background(Component):
|
|
107
129
|
|
108
130
|
if not self.light_version:
|
109
131
|
self.generate_obj_files()
|
132
|
+
self.generate_water_resources_obj()
|
110
133
|
else:
|
111
134
|
self.logger.info("Light version is enabled, obj files will not be generated.")
|
112
135
|
|
@@ -223,13 +246,20 @@ class Background(Component):
|
|
223
246
|
return main_dem_path
|
224
247
|
|
225
248
|
# pylint: disable=too-many-locals
|
226
|
-
def plane_from_np(
|
249
|
+
def plane_from_np(
|
250
|
+
self,
|
251
|
+
dem_data: np.ndarray,
|
252
|
+
save_path: str,
|
253
|
+
is_preview: bool = False,
|
254
|
+
include_zeros: bool = True,
|
255
|
+
) -> None:
|
227
256
|
"""Generates a 3D obj file based on DEM data.
|
228
257
|
|
229
258
|
Arguments:
|
230
259
|
dem_data (np.ndarray) -- The DEM data as a numpy array.
|
231
260
|
save_path (str) -- The path where the obj file will be saved.
|
232
261
|
is_preview (bool, optional) -- If True, the preview mesh will be generated.
|
262
|
+
include_zeros (bool, optional) -- If True, the mesh will include the zero height values.
|
233
263
|
"""
|
234
264
|
dem_data = cv2.resize( # pylint: disable=no-member
|
235
265
|
dem_data, (0, 0), fx=RESIZE_FACTOR, fy=RESIZE_FACTOR
|
@@ -247,6 +277,9 @@ class Background(Component):
|
|
247
277
|
x, y = np.meshgrid(x, y)
|
248
278
|
z = dem_data
|
249
279
|
|
280
|
+
ground = z.max()
|
281
|
+
self.logger.debug("Ground level: %s", ground)
|
282
|
+
|
250
283
|
self.logger.debug(
|
251
284
|
"Starting to generate a mesh for with shape: %s x %s. This may take a while...",
|
252
285
|
cols,
|
@@ -256,6 +289,8 @@ class Background(Component):
|
|
256
289
|
vertices = np.column_stack([x.ravel(), y.ravel(), z.ravel()])
|
257
290
|
faces = []
|
258
291
|
|
292
|
+
skipped = 0
|
293
|
+
|
259
294
|
for i in range(rows - 1):
|
260
295
|
for j in range(cols - 1):
|
261
296
|
top_left = i * cols + j
|
@@ -263,9 +298,15 @@ class Background(Component):
|
|
263
298
|
bottom_left = top_left + cols
|
264
299
|
bottom_right = bottom_left + 1
|
265
300
|
|
301
|
+
if ground in [z[i, j], z[i, j + 1], z[i + 1, j], z[i + 1, j + 1]]:
|
302
|
+
skipped += 1
|
303
|
+
continue
|
304
|
+
|
266
305
|
faces.append([top_left, bottom_left, bottom_right])
|
267
306
|
faces.append([top_left, bottom_right, top_right])
|
268
307
|
|
308
|
+
self.logger.debug("Skipped faces: %s", skipped)
|
309
|
+
|
269
310
|
faces = np.array(faces) # type: ignore
|
270
311
|
mesh = trimesh.Trimesh(vertices=vertices, faces=faces)
|
271
312
|
|
@@ -283,13 +324,14 @@ class Background(Component):
|
|
283
324
|
mesh.apply_scale([0.5, 0.5, 0.5])
|
284
325
|
self.mesh_to_stl(mesh)
|
285
326
|
else:
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
327
|
+
if not include_zeros:
|
328
|
+
multiplier = self.kwargs.get("multiplier", DEFAULT_MULTIPLIER)
|
329
|
+
if multiplier != 1:
|
330
|
+
z_scaling_factor = 1 / multiplier
|
331
|
+
else:
|
332
|
+
z_scaling_factor = 1 / 2**5
|
333
|
+
self.logger.debug("Z scaling factor: %s", z_scaling_factor)
|
334
|
+
mesh.apply_scale([1 / RESIZE_FACTOR, 1 / RESIZE_FACTOR, z_scaling_factor])
|
293
335
|
|
294
336
|
mesh.export(save_path)
|
295
337
|
self.logger.debug("Obj file saved: %s", save_path)
|
@@ -413,3 +455,123 @@ class Background(Component):
|
|
413
455
|
|
414
456
|
cv2.imwrite(colored_dem_path, dem_data_colored)
|
415
457
|
return colored_dem_path
|
458
|
+
|
459
|
+
def create_background_textures(self) -> None:
|
460
|
+
"""Creates background textures for the map."""
|
461
|
+
if not os.path.isfile(self.game.texture_schema):
|
462
|
+
self.logger.warning("Texture schema file not found: %s", self.game.texture_schema)
|
463
|
+
return
|
464
|
+
|
465
|
+
with open(self.game.texture_schema, "r", encoding="utf-8") as f:
|
466
|
+
layers_schema = json.load(f)
|
467
|
+
|
468
|
+
background_layers = []
|
469
|
+
for layer in layers_schema:
|
470
|
+
if layer.get("background") is True:
|
471
|
+
layer_copy = deepcopy(layer)
|
472
|
+
layer_copy["count"] = 1
|
473
|
+
layer_copy["name"] = f"{layer['name']}_background"
|
474
|
+
background_layers.append(layer_copy)
|
475
|
+
|
476
|
+
if not background_layers:
|
477
|
+
return
|
478
|
+
|
479
|
+
self.background_texture = Texture( # pylint: disable=W0201
|
480
|
+
self.game,
|
481
|
+
self.map,
|
482
|
+
self.coordinates,
|
483
|
+
self.background_size,
|
484
|
+
self.rotated_size,
|
485
|
+
rotation=self.rotation,
|
486
|
+
map_directory=self.map_directory,
|
487
|
+
logger=self.logger,
|
488
|
+
light_version=self.light_version,
|
489
|
+
custom_schema=background_layers,
|
490
|
+
)
|
491
|
+
|
492
|
+
self.background_texture.preprocess()
|
493
|
+
self.background_texture.process()
|
494
|
+
|
495
|
+
processed_layers = self.background_texture.get_background_layers()
|
496
|
+
weights_directory = self.game.weights_dir_path(self.map_directory)
|
497
|
+
background_paths = [layer.path(weights_directory) for layer in processed_layers]
|
498
|
+
self.logger.debug("Found %s background textures.", len(background_paths))
|
499
|
+
|
500
|
+
if not background_paths:
|
501
|
+
self.logger.warning("No background textures found.")
|
502
|
+
return
|
503
|
+
|
504
|
+
# Merge all images into one.
|
505
|
+
background_image = np.zeros((self.background_size, self.background_size), dtype=np.uint8)
|
506
|
+
for path in background_paths:
|
507
|
+
layer = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
|
508
|
+
background_image = cv2.add(background_image, layer) # type: ignore
|
509
|
+
|
510
|
+
background_save_path = os.path.join(self.water_directory, "water_resources.png")
|
511
|
+
cv2.imwrite(background_save_path, background_image)
|
512
|
+
self.logger.info("Background texture saved: %s", background_save_path)
|
513
|
+
self.water_resources_path = background_save_path # pylint: disable=W0201
|
514
|
+
|
515
|
+
def subtraction(self) -> None:
|
516
|
+
"""Subtracts the water depth from the DEM data where the water resources are located."""
|
517
|
+
if not self.water_resources_path:
|
518
|
+
self.logger.warning("Water resources texture not found.")
|
519
|
+
return
|
520
|
+
|
521
|
+
# Single channeled 8 bit image, where the water have values of 255, and the rest 0.
|
522
|
+
water_resources_image = cv2.imread(self.water_resources_path, cv2.IMREAD_UNCHANGED)
|
523
|
+
mask = water_resources_image == 255
|
524
|
+
|
525
|
+
# Make mask a little bit smaller (1 pixel).
|
526
|
+
mask = cv2.erode(mask.astype(np.uint8), np.ones((3, 3), np.uint8), iterations=1).astype(
|
527
|
+
bool
|
528
|
+
)
|
529
|
+
|
530
|
+
for output_path in self.output_paths:
|
531
|
+
if FULL_PREVIEW_NAME in output_path:
|
532
|
+
continue
|
533
|
+
dem_image = cv2.imread(output_path, cv2.IMREAD_UNCHANGED)
|
534
|
+
|
535
|
+
# Create a mask where water_resources_image is 255 (or not 0)
|
536
|
+
# Subtract water_depth from dem_image where mask is True
|
537
|
+
dem_image[mask] = dem_image[mask] - self.water_depth
|
538
|
+
|
539
|
+
# Save the modified dem_image back to the output path
|
540
|
+
cv2.imwrite(output_path, dem_image)
|
541
|
+
self.logger.debug("Water depth subtracted from DEM data: %s", output_path)
|
542
|
+
|
543
|
+
def generate_water_resources_obj(self) -> None:
|
544
|
+
"""Generates 3D obj files based on water resources data."""
|
545
|
+
if not self.water_resources_path:
|
546
|
+
self.logger.warning("Water resources texture not found.")
|
547
|
+
return
|
548
|
+
|
549
|
+
# Single channeled 8 bit image, where the water have values of 255, and the rest 0.
|
550
|
+
plane_water = cv2.imread(self.water_resources_path, cv2.IMREAD_UNCHANGED)
|
551
|
+
dilated_plane_water = cv2.dilate(
|
552
|
+
plane_water.astype(np.uint8), np.ones((5, 5), np.uint8), iterations=5
|
553
|
+
).astype(np.uint8)
|
554
|
+
plane_save_path = os.path.join(self.water_directory, "plane_water.obj")
|
555
|
+
self.plane_from_np(
|
556
|
+
dilated_plane_water, plane_save_path, is_preview=False, include_zeros=False
|
557
|
+
)
|
558
|
+
|
559
|
+
# Single channeled 16 bit DEM image of terrain.
|
560
|
+
background_dem = cv2.imread(self.not_substracted_path, cv2.IMREAD_UNCHANGED)
|
561
|
+
|
562
|
+
# Remove all the values from the background dem where the plane_water is 0.
|
563
|
+
background_dem[plane_water == 0] = 0
|
564
|
+
|
565
|
+
# Dilate the background dem to make the water more smooth.
|
566
|
+
elevated_water = cv2.dilate(background_dem, np.ones((3, 3), np.uint16), iterations=10)
|
567
|
+
|
568
|
+
# Use the background dem as a mask to prevent the original values from being overwritten.
|
569
|
+
mask = background_dem > 0
|
570
|
+
|
571
|
+
# Combine the dilated background dem with non-dilated background dem.
|
572
|
+
elevated_water = np.where(mask, background_dem, elevated_water)
|
573
|
+
elevated_save_path = os.path.join(self.water_directory, "elevated_water.obj")
|
574
|
+
|
575
|
+
self.plane_from_np(
|
576
|
+
elevated_water, elevated_save_path, is_preview=False, include_zeros=False
|
577
|
+
)
|
maps4fs/generator/component.py
CHANGED
@@ -330,6 +330,7 @@ class Component:
|
|
330
330
|
|
331
331
|
return cs_x, cs_y
|
332
332
|
|
333
|
+
# pylint: disable=R0914
|
333
334
|
def fit_polygon_into_bounds(
|
334
335
|
self, polygon_points: list[tuple[int, int]], margin: int = 0, angle: int = 0
|
335
336
|
) -> list[tuple[int, int]]:
|
@@ -371,8 +372,13 @@ class Component:
|
|
371
372
|
bounds = box(min_x, min_y, max_x, max_y)
|
372
373
|
|
373
374
|
# Intersect the polygon with the bounds to fit it within the map
|
374
|
-
|
375
|
-
|
375
|
+
try:
|
376
|
+
fitted_polygon = polygon.intersection(bounds)
|
377
|
+
self.logger.debug("Fitted the polygon into the bounds: %s", bounds)
|
378
|
+
except Exception as e:
|
379
|
+
raise ValueError( # pylint: disable=W0707
|
380
|
+
f"Could not fit the polygon into the bounds: {e}"
|
381
|
+
)
|
376
382
|
|
377
383
|
if not isinstance(fitted_polygon, Polygon):
|
378
384
|
raise ValueError("The fitted polygon is not a valid polygon.")
|
maps4fs/generator/texture.py
CHANGED
@@ -64,6 +64,7 @@ class Texture(Component):
|
|
64
64
|
priority: int | None = None,
|
65
65
|
info_layer: str | None = None,
|
66
66
|
usage: str | None = None,
|
67
|
+
background: bool = False,
|
67
68
|
):
|
68
69
|
self.name = name
|
69
70
|
self.count = count
|
@@ -74,6 +75,7 @@ class Texture(Component):
|
|
74
75
|
self.priority = priority
|
75
76
|
self.info_layer = info_layer
|
76
77
|
self.usage = usage
|
78
|
+
self.background = background
|
77
79
|
|
78
80
|
def to_json(self) -> dict[str, str | list[str] | bool]: # type: ignore
|
79
81
|
"""Returns dictionary with layer data.
|
@@ -90,6 +92,7 @@ class Texture(Component):
|
|
90
92
|
"priority": self.priority,
|
91
93
|
"info_layer": self.info_layer,
|
92
94
|
"usage": self.usage,
|
95
|
+
"background": self.background,
|
93
96
|
}
|
94
97
|
|
95
98
|
data = {k: v for k, v in data.items() if v is not None}
|
@@ -178,17 +181,30 @@ class Texture(Component):
|
|
178
181
|
self.fields_padding = self.kwargs.get("fields_padding", 0)
|
179
182
|
self.logger.debug("Light version: %s.", self.light_version)
|
180
183
|
|
181
|
-
|
182
|
-
|
184
|
+
self.custom_schema: list[dict[str, str | dict[str, str] | int]] | None = self.kwargs.get(
|
185
|
+
"custom_schema"
|
186
|
+
)
|
183
187
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
188
|
+
if self.custom_schema:
|
189
|
+
layers_schema = self.custom_schema
|
190
|
+
self.logger.info("Custom schema loaded with %s layers.", len(layers_schema))
|
191
|
+
else:
|
192
|
+
if not os.path.isfile(self.game.texture_schema):
|
193
|
+
raise FileNotFoundError(
|
194
|
+
f"Texture layers schema not found: {self.game.texture_schema}"
|
195
|
+
)
|
196
|
+
|
197
|
+
try:
|
198
|
+
with open(self.game.texture_schema, "r", encoding="utf-8") as f:
|
199
|
+
layers_schema = json.load(f)
|
200
|
+
except json.JSONDecodeError as e:
|
201
|
+
raise ValueError(f"Error loading texture layers schema: {e}") from e
|
189
202
|
|
190
|
-
|
191
|
-
|
203
|
+
try:
|
204
|
+
self.layers = [self.Layer.from_json(layer) for layer in layers_schema]
|
205
|
+
self.logger.info("Loaded %s layers.", len(self.layers))
|
206
|
+
except Exception as e: # pylint: disable=W0703
|
207
|
+
raise ValueError(f"Error loading texture layers: {e}") from e
|
192
208
|
|
193
209
|
base_layer = self.get_base_layer()
|
194
210
|
if base_layer:
|
@@ -215,6 +231,14 @@ class Texture(Component):
|
|
215
231
|
return layer
|
216
232
|
return None
|
217
233
|
|
234
|
+
def get_background_layers(self) -> list[Layer]:
|
235
|
+
"""Returns list of background layers.
|
236
|
+
|
237
|
+
Returns:
|
238
|
+
list[Layer]: List of background layers.
|
239
|
+
"""
|
240
|
+
return [layer for layer in self.layers if layer.background]
|
241
|
+
|
218
242
|
def get_layer_by_usage(self, usage: str) -> Layer | None:
|
219
243
|
"""Returns layer by usage.
|
220
244
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: maps4fs
|
3
|
-
Version: 1.2.
|
3
|
+
Version: 1.2.5
|
4
4
|
Summary: Generate map templates for Farming Simulator from real places.
|
5
5
|
Author-email: iwatkot <iwatkot@gmail.com>
|
6
6
|
License: MIT License
|
@@ -70,6 +70,7 @@ Requires-Dist: pympler
|
|
70
70
|
🌽 Automatically generates farmlands 🆕<br>
|
71
71
|
🌿 Automatically generates decorative foliage 🆕<br>
|
72
72
|
🌲 Automatically generates forests 🆕<br>
|
73
|
+
🌊 Automatically generates water planes 🆕<br>
|
73
74
|
🌍 Based on real-world data from OpenStreetMap<br>
|
74
75
|
🏞️ Generates height map using SRTM dataset<br>
|
75
76
|
📦 Provides a ready-to-use map template for the Giants Editor<br>
|
@@ -90,6 +91,8 @@ Requires-Dist: pympler
|
|
90
91
|
🌿 Automatically generates decorative foliage.<br><br>
|
91
92
|
<img src="https://github.com/user-attachments/assets/27a5e541-a9f5-4504-b8d2-64aae9fb3e52"><br>
|
92
93
|
🌲 Automatically generates forests.<br><br>
|
94
|
+
<img src="https://github.com/user-attachments/assets/cce7d4e0-cba2-4dd2-b22d-03137fb2e860"><br>
|
95
|
+
🌊 Automatically generates water planes.<br><br>
|
93
96
|
<img src="https://github.com/user-attachments/assets/80e5923c-22c7-4dc0-8906-680902511f3a"><br>
|
94
97
|
🗒️ True-to-life blueprints for fast and precise modding.<br><br>
|
95
98
|
<img width="480" src="https://github.com/user-attachments/assets/1a8802d2-6a3b-4bfa-af2b-7c09478e199b"><br>
|
@@ -101,6 +104,9 @@ Requires-Dist: pympler
|
|
101
104
|
<a href="https://www.youtube.com/watch?v=Nl_aqXJ5nAk" target="_blank"><img src="https://github.com/user-attachments/assets/4845e030-0e73-47ab-a5a3-430308913060"/></a>
|
102
105
|
<p align="center"><i>How to Generate a Map for Farming Simulator 25 and 22 from a real place using maps4FS.</i></p>
|
103
106
|
|
107
|
+

|
108
|
+
<p align="center"><i>Map example generated with maps4fs.</i></p>
|
109
|
+
|
104
110
|
## Quick Start
|
105
111
|
There are several ways to use the tool. You obviously need the **first one**, but you can choose any of the others depending on your needs.<br>
|
106
112
|
### 🚜 For most users
|
@@ -476,6 +482,8 @@ You can also apply some advanced settings to the map generation process. Note th
|
|
476
482
|
|
477
483
|
- Plateau height: this value will be added to each pixel of the DEM image, making it "higher". It's useful when you want to add some negative heights on the map, that appear to be in a "low" place. By default, it's set to 0.
|
478
484
|
|
485
|
+
- Water depth: this value will be subtracted from each pixel of the DEM image, where water resources are located. Pay attention that it's not in meters, instead it in the pixel value of DEM, which is 16 bit image with possible values from 0 to 65535. When this value is set, the same value will be added to the plateau setting to avoid negative heights.
|
486
|
+
|
479
487
|
### Texture Advanced settings
|
480
488
|
|
481
489
|
- Fields padding - this value (in meters) will be applied to each field, making it smaller. It's useful when the fields are too close to each other and you want to make them smaller. By default, it's set to 0.
|
@@ -1,8 +1,8 @@
|
|
1
1
|
maps4fs/__init__.py,sha256=da4jmND2Ths9AffnkAKgzLHNkvKFOc_l21gJisPXqWY,155
|
2
2
|
maps4fs/logger.py,sha256=B-NEYpMjPAAqlV4VpfTi6nbBFnEABVtQOaYe6nMpidg,1489
|
3
3
|
maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
4
|
-
maps4fs/generator/background.py,sha256=
|
5
|
-
maps4fs/generator/component.py,sha256=
|
4
|
+
maps4fs/generator/background.py,sha256=21xB-xn2A6QGdX9UVWqvzoW-L6JWPAZOqCcIhR8nxKU,22689
|
5
|
+
maps4fs/generator/component.py,sha256=SeI1xfwo9I4lrkcOcHyjxMffHsG8OXc80-mNsR2zpPw,17748
|
6
6
|
maps4fs/generator/config.py,sha256=b7qY0luC-_WM_c72Ohtlf4FrB37X5cALInbestSdUsw,4382
|
7
7
|
maps4fs/generator/dem.py,sha256=rc7ADzjvlZzStOqagsWW0Vrm9-X86aPpoR1RhBF_-OE,16025
|
8
8
|
maps4fs/generator/game.py,sha256=ZQeYzPzPB3CG41avdhNCyTZpHEeedqNBuAbNevTZuXg,7931
|
@@ -10,12 +10,12 @@ maps4fs/generator/grle.py,sha256=3hcr5e2YLXemFi-_x2cLHWbMVb06591k0PZxaBVovH8,176
|
|
10
10
|
maps4fs/generator/i3d.py,sha256=oK5pKjzvT-gydma5Q6CcDYTVODGxK7MIGajLrAV9JkU,18370
|
11
11
|
maps4fs/generator/map.py,sha256=lA1MNAcMwsDtsYxbwwm7DjwP3zraHKnri_xnLUu30j0,5326
|
12
12
|
maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
|
13
|
-
maps4fs/generator/texture.py,sha256=
|
13
|
+
maps4fs/generator/texture.py,sha256=vgiwJNIl14JABhNOBGh_W8SBkAUNQN3TjNJayR76va0,27468
|
14
14
|
maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
15
15
|
maps4fs/toolbox/background.py,sha256=9BXWNqs_n3HgqDiPztWylgYk_QM4YgBpe6_ZNQAWtSc,2154
|
16
16
|
maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
|
17
|
-
maps4fs-1.2.
|
18
|
-
maps4fs-1.2.
|
19
|
-
maps4fs-1.2.
|
20
|
-
maps4fs-1.2.
|
21
|
-
maps4fs-1.2.
|
17
|
+
maps4fs-1.2.5.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
|
18
|
+
maps4fs-1.2.5.dist-info/METADATA,sha256=Ta281p_H7YvXYWdG9GRIHtsa12FTEDVCilsxJFZZR_Q,30600
|
19
|
+
maps4fs-1.2.5.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
20
|
+
maps4fs-1.2.5.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
|
21
|
+
maps4fs-1.2.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|