make LevelRenderData into a dataclass
This commit is contained in:
parent
034f8fe463
commit
9f264d1f59
3 changed files with 215 additions and 153 deletions
|
@ -26,11 +26,11 @@ class AltitudeAreaGeometries:
|
|||
self.obstacles = obstacles
|
||||
|
||||
@property
|
||||
def min_altitude(self):
|
||||
def min_altitude(self) -> float:
|
||||
return self.altitude if self.altitude is not None else min(p.altitude for p in self.points)
|
||||
|
||||
@property
|
||||
def max_altitude(self):
|
||||
def max_altitude(self) -> float:
|
||||
return self.altitude if self.altitude is not None else max(p.altitude for p in self.points)
|
||||
|
||||
def get_altitudes(self, points):
|
||||
|
|
|
@ -6,12 +6,11 @@ from functools import reduce
|
|||
from itertools import chain
|
||||
|
||||
import numpy as np
|
||||
from django.db.backends.ddl_references import Columns
|
||||
from shapely import prepared
|
||||
from shapely.geometry import GeometryCollection, Polygon, MultiPolygon
|
||||
from shapely.ops import unary_union
|
||||
|
||||
from c3nav.mapdata.models import Area, Space
|
||||
from c3nav.mapdata.models import Space, Level, AltitudeArea
|
||||
from c3nav.mapdata.render.geometry.altitudearea import AltitudeAreaGeometries
|
||||
from c3nav.mapdata.render.geometry.hybrid import HybridGeometry
|
||||
from c3nav.mapdata.render.geometry.mesh import Mesh
|
||||
|
@ -28,45 +27,46 @@ empty_geometry_collection = GeometryCollection()
|
|||
ZeroOrMorePolygons: typing.TypeAlias = GeometryCollection | Polygon | MultiPolygon
|
||||
|
||||
|
||||
@dataclass
|
||||
class LevelGeometries:
|
||||
"""
|
||||
Store geometries for a Level.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.buildings = None
|
||||
self.altitudeareas = []
|
||||
self.heightareas = []
|
||||
self.walls = None
|
||||
self.walls_extended = None
|
||||
self.all_walls = None
|
||||
self.short_walls = []
|
||||
self.doors = None
|
||||
self.doors_extended = None
|
||||
self.holes = None
|
||||
self.access_restriction_affected = None
|
||||
self.restricted_spaces_indoors = None
|
||||
self.restricted_spaces_outdoors = None
|
||||
self.affected_area = None
|
||||
self.ramps = []
|
||||
# todo: split into the two versions of this
|
||||
buildings: ZeroOrMorePolygons
|
||||
altitudeareas: list[AltitudeAreaGeometries]
|
||||
heightareas: typing.Sequence[tuple[ZeroOrMorePolygons, float]]
|
||||
walls: ZeroOrMorePolygons
|
||||
walls_extended: None | HybridGeometry
|
||||
all_walls: ZeroOrMorePolygons
|
||||
short_walls: list[tuple[AltitudeArea, ZeroOrMorePolygons]] | typing.Sequence[ZeroOrMorePolygons]
|
||||
doors: ZeroOrMorePolygons | None
|
||||
doors_extended: HybridGeometry | None
|
||||
holes: None
|
||||
access_restriction_affected: dict[int, ZeroOrMorePolygons] | None
|
||||
restricted_spaces_indoors: dict[int, ZeroOrMorePolygons]
|
||||
restricted_spaces_outdoors: dict[int, ZeroOrMorePolygons]
|
||||
affected_area: ZeroOrMorePolygons | None
|
||||
ramps: typing.Sequence[ZeroOrMorePolygons]
|
||||
|
||||
self.vertices = None
|
||||
self.faces = None
|
||||
vertices: None | np.ndarray
|
||||
faces: None | np.ndarray
|
||||
|
||||
self.walls_base = None
|
||||
self.walls_bottom = None
|
||||
walls_base: None | HybridGeometry
|
||||
walls_bottom: None | HybridGeometry
|
||||
|
||||
self.pk = None
|
||||
self.on_top_of_id = None
|
||||
self.short_label = None
|
||||
self.base_altitude = None
|
||||
self.default_height = None
|
||||
self.door_height = None
|
||||
self.min_altitude = None
|
||||
self.max_altitude = None
|
||||
self.max_height = None
|
||||
pk: int
|
||||
on_top_of_id: int | None
|
||||
short_label: str
|
||||
base_altitude: int
|
||||
default_height: int
|
||||
door_height: int
|
||||
min_altitude: int
|
||||
max_altitude: int
|
||||
max_height: int
|
||||
|
||||
self.lower_bound = None
|
||||
self.upper_bound = None
|
||||
lower_bound: int
|
||||
upper_bound: None
|
||||
|
||||
def __repr__(self):
|
||||
return '<LevelGeometries for Level %s (#%d)>' % (self.short_label, self.pk)
|
||||
|
@ -80,9 +80,9 @@ class LevelGeometries:
|
|||
instance: Space
|
||||
|
||||
@classmethod
|
||||
def spaces_for_level(cls, level, buildings_geom) -> list[SpaceGeometries]:
|
||||
def spaces_for_level(cls, level: Level, buildings_geom: ZeroOrMorePolygons) -> list[SpaceGeometries]:
|
||||
spaces: list[cls.SpaceGeometries] = []
|
||||
for space in level.spaces.all():
|
||||
for space in level.spaces.all(): # noqa
|
||||
geometry = space.geometry
|
||||
subtract = []
|
||||
if space.outside:
|
||||
|
@ -124,7 +124,7 @@ class LevelGeometries:
|
|||
ramps: list[ZeroOrMorePolygons]
|
||||
|
||||
@classmethod
|
||||
def analyze_spaces(cls, level, spaces: list[SpaceGeometries], walkable_spaces_geom: ZeroOrMorePolygons,
|
||||
def analyze_spaces(cls, level: Level, spaces: list[SpaceGeometries], walkable_spaces_geom: ZeroOrMorePolygons,
|
||||
buildings_geom: ZeroOrMorePolygons, color_manager: 'ThemeColorManager') -> Analysis:
|
||||
buildings_geom_prep = prepared.prep(buildings_geom)
|
||||
|
||||
|
@ -145,7 +145,7 @@ class LevelGeometries:
|
|||
for space in spaces:
|
||||
buffered = space.geometry.buffer(0.01).union(unary_union(tuple(
|
||||
unwrap_geom(door.geometry)
|
||||
for door in level.doors.all() if door.geometry.intersects(unwrap_geom(space.geometry))
|
||||
for door in level.doors.all() if door.geometry.intersects(unwrap_geom(space.geometry)) # noqa
|
||||
)).difference(walkable_spaces_geom))
|
||||
intersects = buildings_geom_prep.intersects(buffered)
|
||||
|
||||
|
@ -236,36 +236,12 @@ class LevelGeometries:
|
|||
|
||||
ramps=ramps,
|
||||
)
|
||||
|
||||
|
||||
@classmethod
|
||||
def build_for_level(cls, level, color_manager: 'ThemeColorManager', altitudeareas_above):
|
||||
geoms = LevelGeometries()
|
||||
buildings_geom = unary_union([unwrap_geom(b.geometry) for b in level.buildings.all()])
|
||||
|
||||
# remove columns and holes from space areas
|
||||
spaces = cls.spaces_for_level(level, buildings_geom)
|
||||
|
||||
spaces_geom = unary_union([unwrap_geom(space.geometry) for space in spaces])
|
||||
doors_geom = unary_union([unwrap_geom(d.geometry) for d in level.doors.all()])
|
||||
doors_geom = doors_geom.intersection(buildings_geom)
|
||||
walkable_spaces_geom = unary_union([unwrap_geom(space.walkable_geom) for space in spaces])
|
||||
doors_geom = doors_geom.difference(walkable_spaces_geom)
|
||||
if level.on_top_of_id is None:
|
||||
geoms.holes = unary_union([s.holes_geom for s in spaces])
|
||||
|
||||
analysis = cls.analyze_spaces(
|
||||
level=level,
|
||||
spaces=spaces,
|
||||
walkable_spaces_geom=walkable_spaces_geom,
|
||||
buildings_geom=buildings_geom,
|
||||
color_manager=color_manager
|
||||
)
|
||||
|
||||
geoms.buildings = buildings_geom
|
||||
geoms.doors = doors_geom
|
||||
|
||||
def build_altitudeareas(cls, level: Level, analysis: Analysis) -> list[AltitudeAreaGeometries]:
|
||||
# add altitudegroup geometries and split ground colors into them
|
||||
for altitudearea in level.altitudeareas.all():
|
||||
altitudearea_geoms: list[AltitudeAreaGeometries] = []
|
||||
for altitudearea in level.altitudeareas.all(): # noqa
|
||||
altitudearea_prep = prepared.prep(unwrap_geom(altitudearea.geometry))
|
||||
altitudearea_colors = {color: {access_restriction: area.intersection(unwrap_geom(altitudearea.geometry))
|
||||
for access_restriction, area in areas.items()
|
||||
|
@ -286,59 +262,121 @@ class LevelGeometries:
|
|||
if new_height_obstacles:
|
||||
altitudearea_obstacles[height] = new_height_obstacles
|
||||
|
||||
geoms.altitudeareas.append(AltitudeAreaGeometries(altitudearea,
|
||||
altitudearea_colors,
|
||||
altitudearea_obstacles))
|
||||
|
||||
# merge height areas
|
||||
geoms.heightareas = tuple((unary_union(geoms), height)
|
||||
for height, geoms in sorted(analysis.heightareas.items(), key=operator.itemgetter(0)))
|
||||
|
||||
# merge access restrictions
|
||||
geoms.access_restriction_affected = {
|
||||
access_restriction: unary_union([unwrap_geom(geom) for geom in areas])
|
||||
for access_restriction, areas in analysis.access_restriction_affected.items()
|
||||
}
|
||||
geoms.restricted_spaces_indoors = {
|
||||
access_restriction: unary_union(spaces)
|
||||
for access_restriction, spaces in analysis.restricted_spaces_indoors.items()
|
||||
}
|
||||
geoms.restricted_spaces_outdoors = {
|
||||
access_restriction: unary_union(spaces)
|
||||
for access_restriction, spaces in analysis.restricted_spaces_outdoors.items()
|
||||
}
|
||||
|
||||
AccessRestrictionAffected.build(geoms.access_restriction_affected).save_level(level.pk, 'base')
|
||||
|
||||
geoms.walls = buildings_geom.difference(unary_union((spaces_geom, doors_geom)))
|
||||
|
||||
# shorten walls if there are altitudeareas above
|
||||
remaining = geoms.walls
|
||||
altitudearea_geoms.append(AltitudeAreaGeometries(
|
||||
altitudearea=altitudearea,
|
||||
colors=altitudearea_colors,
|
||||
obstacles=altitudearea_obstacles
|
||||
))
|
||||
return altitudearea_geoms
|
||||
|
||||
@classmethod
|
||||
def build_short_walls(cls, altitudeareas_above,
|
||||
walls_geom: ZeroOrMorePolygons) -> list[tuple[AltitudeArea, ZeroOrMorePolygons]]:
|
||||
remaining = walls_geom
|
||||
short_walls = []
|
||||
for altitudearea in altitudeareas_above:
|
||||
intersection = altitudearea.geometry.intersection(remaining).buffer(0)
|
||||
if intersection.is_empty:
|
||||
continue
|
||||
remaining = remaining.difference(unwrap_geom(altitudearea.geometry))
|
||||
geoms.short_walls.append((altitudearea, intersection))
|
||||
geoms.all_walls = geoms.walls
|
||||
geoms.walls = geoms.walls.difference(
|
||||
unary_union(tuple(unwrap_geom(altitudearea.geometry) for altitudearea in altitudeareas_above))
|
||||
short_walls.append((altitudearea, intersection))
|
||||
return short_walls
|
||||
|
||||
@classmethod
|
||||
def build_for_level(cls, level: Level, color_manager: 'ThemeColorManager', altitudeareas_above):
|
||||
buildings_geom = unary_union([unwrap_geom(b.geometry) for b in level.buildings.all()]) # noqa
|
||||
|
||||
# remove columns and holes from space areas
|
||||
spaces = cls.spaces_for_level(level, buildings_geom)
|
||||
|
||||
spaces_geom = unary_union([unwrap_geom(space.geometry) for space in spaces])
|
||||
doors_geom = unary_union([unwrap_geom(d.geometry) for d in level.doors.all()]) # noqa
|
||||
doors_geom = doors_geom.intersection(buildings_geom)
|
||||
walkable_spaces_geom = unary_union([unwrap_geom(space.walkable_geom) for space in spaces])
|
||||
doors_geom = doors_geom.difference(walkable_spaces_geom)
|
||||
walls_geom = buildings_geom.difference(unary_union((spaces_geom, doors_geom)))
|
||||
if level.on_top_of_id is None:
|
||||
holes_geom = unary_union([s.holes_geom for s in spaces])
|
||||
else:
|
||||
holes_geom = None
|
||||
|
||||
analysis = cls.analyze_spaces(
|
||||
level=level,
|
||||
spaces=spaces,
|
||||
walkable_spaces_geom=walkable_spaces_geom,
|
||||
buildings_geom=buildings_geom,
|
||||
color_manager=color_manager
|
||||
)
|
||||
|
||||
# general level infos
|
||||
geoms.pk = level.pk
|
||||
geoms.on_top_of_id = level.on_top_of_id
|
||||
geoms.short_label = level.short_label
|
||||
geoms.base_altitude = int(level.base_altitude * 1000)
|
||||
geoms.default_height = int(level.default_height * 1000)
|
||||
geoms.door_height = int(level.door_height * 1000)
|
||||
geoms.min_altitude = (min(area.min_altitude for area in geoms.altitudeareas)
|
||||
if geoms.altitudeareas else geoms.base_altitude)
|
||||
geoms.max_altitude = (max(area.max_altitude for area in geoms.altitudeareas)
|
||||
if geoms.altitudeareas else geoms.base_altitude)
|
||||
geoms.max_height = (min(height for area, height in geoms.heightareas)
|
||||
if geoms.heightareas else geoms.default_height)
|
||||
geoms.lower_bound = geoms.min_altitude-700
|
||||
altitudearea_geoms = cls.build_altitudeareas(level=level, analysis=analysis)
|
||||
heightareas_geom = tuple((unary_union(geoms), height) for height, geoms in
|
||||
sorted(analysis.heightareas.items(), key=operator.itemgetter(0)))
|
||||
|
||||
base_altitude = int(level.base_altitude * 1000)
|
||||
default_height = int(level.default_height * 1000)
|
||||
door_height = int(level.door_height * 1000)
|
||||
|
||||
min_altitude = (min(area.min_altitude for area in altitudearea_geoms) if altitudearea_geoms else base_altitude)
|
||||
|
||||
# hybrid geometries
|
||||
|
||||
geoms = cls(
|
||||
ramps=analysis.ramps,
|
||||
|
||||
buildings=buildings_geom,
|
||||
doors=doors_geom,
|
||||
holes=holes_geom,
|
||||
|
||||
altitudeareas=altitudearea_geoms,
|
||||
heightareas=heightareas_geom,
|
||||
|
||||
# merge access restrictions
|
||||
access_restriction_affected={
|
||||
access_restriction: unary_union([unwrap_geom(geom) for geom in areas])
|
||||
for access_restriction, areas in analysis.access_restriction_affected.items()
|
||||
},
|
||||
restricted_spaces_indoors={
|
||||
access_restriction: unary_union(spaces)
|
||||
for access_restriction, spaces in analysis.restricted_spaces_indoors.items()
|
||||
},
|
||||
restricted_spaces_outdoors={
|
||||
access_restriction: unary_union(spaces)
|
||||
for access_restriction, spaces in analysis.restricted_spaces_outdoors.items()
|
||||
},
|
||||
|
||||
# shorten walls if there are altitudeareas above
|
||||
short_walls=cls.build_short_walls(altitudeareas_above, walls_geom),
|
||||
|
||||
all_walls=walls_geom,
|
||||
walls=walls_geom.difference(
|
||||
unary_union(tuple(unwrap_geom(altitudearea.geometry) for altitudearea in altitudeareas_above))
|
||||
),
|
||||
|
||||
# general level infos
|
||||
pk=level.pk,
|
||||
on_top_of_id=level.on_top_of_id,
|
||||
short_label=level.short_label,
|
||||
base_altitude=base_altitude,
|
||||
default_height=default_height,
|
||||
door_height=door_height,
|
||||
min_altitude=min_altitude,
|
||||
max_altitude=(max(area.max_altitude for area in altitudearea_geoms)
|
||||
if altitudearea_geoms else base_altitude),
|
||||
max_height=(min(height for area, height in heightareas_geom)
|
||||
if analysis.heightareas else default_height),
|
||||
lower_bound=min_altitude-700,
|
||||
|
||||
affected_area=None,
|
||||
doors_extended=None,
|
||||
faces=None,
|
||||
upper_bound=None,
|
||||
vertices=None,
|
||||
walls_base=None,
|
||||
walls_bottom=None,
|
||||
walls_extended=None,
|
||||
)
|
||||
|
||||
AccessRestrictionAffected.build(geoms.access_restriction_affected).save_level(level.pk, 'base')
|
||||
|
||||
return geoms
|
||||
|
||||
|
@ -388,7 +426,7 @@ class LevelGeometries:
|
|||
vertex_values = np.empty(self.vertices.shape[:1], dtype=np.int32)
|
||||
if not vertex_values.size:
|
||||
return vertex_values
|
||||
vertex_value_mask = np.full(self.vertices.shape[:1], fill_value=False, dtype=np.bool)
|
||||
vertex_value_mask = np.full(self.vertices.shape[:1], fill_value=False, dtype=bool)
|
||||
|
||||
for item in items:
|
||||
faces = area_func(item).faces
|
||||
|
|
|
@ -206,18 +206,20 @@ class LevelRenderData:
|
|||
elif render_level.pk != level.pk:
|
||||
map_history.composite(MapHistory.open_level(level.pk, 'base'), None)
|
||||
|
||||
new_geoms = LevelGeometries()
|
||||
new_geoms.buildings = crop_to.intersection(old_geoms.buildings)
|
||||
new_buildings_geoms = crop_to.intersection(old_geoms.buildings)
|
||||
if old_geoms.on_top_of_id is None:
|
||||
new_geoms.holes = crop_to.intersection(old_geoms.holes)
|
||||
new_geoms.doors = crop_to.intersection(old_geoms.doors)
|
||||
new_geoms.walls = crop_to.intersection(old_geoms.walls)
|
||||
new_geoms.all_walls = crop_to.intersection(old_geoms.all_walls)
|
||||
new_geoms.short_walls = tuple((altitude, geom) for altitude, geom in tuple(
|
||||
new_holes_geoms = crop_to.intersection(old_geoms.holes)
|
||||
else:
|
||||
new_holes_geoms = None
|
||||
new_doors_geoms = crop_to.intersection(old_geoms.doors)
|
||||
new_walls_geoms = crop_to.intersection(old_geoms.walls)
|
||||
new_all_walls_geoms = crop_to.intersection(old_geoms.all_walls)
|
||||
new_short_walls_geoms = tuple((altitude, geom) for altitude, geom in tuple(
|
||||
(altitude, crop_to.intersection(geom))
|
||||
for altitude, geom in old_geoms.short_walls
|
||||
) if not geom.is_empty)
|
||||
|
||||
new_altitudeareas = []
|
||||
for altitudearea in old_geoms.altitudeareas:
|
||||
new_geometry = crop_to.intersection(unwrap_geom(altitudearea.geometry))
|
||||
if new_geometry.is_empty:
|
||||
|
@ -258,59 +260,81 @@ class LevelRenderData:
|
|||
new_altitudearea_obstacles[height] = new_height_obstacles
|
||||
new_altitudearea.obstacles = new_altitudearea_obstacles
|
||||
|
||||
new_geoms.altitudeareas.append(new_altitudearea)
|
||||
new_altitudeareas.append(new_altitudearea)
|
||||
|
||||
if new_geoms.walls.is_empty and not new_geoms.altitudeareas:
|
||||
if new_walls_geoms.is_empty and not new_altitudeareas:
|
||||
continue
|
||||
|
||||
new_geoms.ramps = tuple(
|
||||
ramp for ramp in (crop_to.intersection(unwrap_geom(ramp)) for ramp in old_geoms.ramps)
|
||||
if not ramp.is_empty
|
||||
)
|
||||
|
||||
new_geoms.heightareas = tuple(
|
||||
new_heightareas = tuple(
|
||||
(area, height) for area, height in ((crop_to.intersection(unwrap_geom(area)), height)
|
||||
for area, height in old_geoms.heightareas)
|
||||
if not area.is_empty
|
||||
)
|
||||
|
||||
new_geoms.affected_area = unary_union((
|
||||
*(altitudearea.geometry for altitudearea in new_geoms.altitudeareas),
|
||||
crop_to.intersection(new_geoms.walls.buffer(1)),
|
||||
*((new_geoms.holes.buffer(1),) if new_geoms.holes else ()),
|
||||
))
|
||||
|
||||
for access_restriction, area in old_geoms.access_restriction_affected.items():
|
||||
new_area = crop_to.intersection(area)
|
||||
if not new_area.is_empty:
|
||||
access_restriction_affected.setdefault(access_restriction, []).append(new_area)
|
||||
|
||||
new_geoms.restricted_spaces_indoors = {}
|
||||
new_restricted_spaces_indoors = {}
|
||||
for access_restriction, area in old_geoms.restricted_spaces_indoors.items():
|
||||
new_area = crop_to.intersection(area)
|
||||
if not new_area.is_empty:
|
||||
new_geoms.restricted_spaces_indoors[access_restriction] = new_area
|
||||
new_restricted_spaces_indoors[access_restriction] = new_area
|
||||
|
||||
new_geoms.restricted_spaces_outdoors = {}
|
||||
new_restricted_spaces_outdoors = {}
|
||||
for access_restriction, area in old_geoms.restricted_spaces_outdoors.items():
|
||||
new_area = crop_to.intersection(area)
|
||||
if not new_area.is_empty:
|
||||
new_geoms.restricted_spaces_outdoors[access_restriction] = new_area
|
||||
new_restricted_spaces_outdoors[access_restriction] = new_area
|
||||
|
||||
new_geoms.pk = old_geoms.pk
|
||||
new_geoms.on_top_of_id = old_geoms.on_top_of_id
|
||||
new_geoms.short_label = old_geoms.short_label
|
||||
new_geoms.base_altitude = old_geoms.base_altitude
|
||||
new_geoms.default_height = old_geoms.default_height
|
||||
new_geoms.door_height = old_geoms.door_height
|
||||
new_geoms.min_altitude = (min(area.min_altitude for area in new_geoms.altitudeareas)
|
||||
if new_geoms.altitudeareas else new_geoms.base_altitude)
|
||||
new_geoms.max_altitude = (max(area.max_altitude for area in new_geoms.altitudeareas)
|
||||
if new_geoms.altitudeareas else new_geoms.base_altitude)
|
||||
new_geoms.max_height = (min(height for area, height in new_geoms.heightareas)
|
||||
if new_geoms.heightareas else new_geoms.default_height)
|
||||
new_geoms.lower_bound = old_geoms.lower_bound
|
||||
new_geoms.upper_bound = old_geoms.upper_bound
|
||||
new_geoms = LevelGeometries(
|
||||
pk=old_geoms.pk,
|
||||
on_top_of_id=old_geoms.on_top_of_id,
|
||||
short_label=old_geoms.short_label,
|
||||
base_altitude=old_geoms.base_altitude,
|
||||
default_height=old_geoms.default_height,
|
||||
door_height=old_geoms.door_height,
|
||||
min_altitude=(min(area.min_altitude for area in new_altitudeareas)
|
||||
if new_altitudeareas else old_geoms.base_altitude),
|
||||
max_altitude=(max(area.max_altitude for area in new_altitudeareas)
|
||||
if new_altitudeareas else old_geoms.base_altitude),
|
||||
max_height=(min(height for area, height in new_heightareas)
|
||||
if new_heightareas else old_geoms.default_height),
|
||||
lower_bound=old_geoms.lower_bound,
|
||||
upper_bound=old_geoms.upper_bound,
|
||||
heightareas=new_heightareas,
|
||||
altitudeareas=new_altitudeareas,
|
||||
|
||||
buildings=new_buildings_geoms,
|
||||
holes=new_holes_geoms,
|
||||
doors=new_doors_geoms,
|
||||
walls=new_walls_geoms,
|
||||
all_walls=new_all_walls_geoms,
|
||||
short_walls=new_short_walls_geoms,
|
||||
|
||||
restricted_spaces_indoors=new_restricted_spaces_indoors,
|
||||
restricted_spaces_outdoors=new_restricted_spaces_outdoors,
|
||||
|
||||
ramps=tuple(
|
||||
ramp for ramp in (crop_to.intersection(unwrap_geom(ramp)) for ramp in old_geoms.ramps)
|
||||
if not ramp.is_empty
|
||||
),
|
||||
|
||||
affected_area=unary_union((
|
||||
*(altitudearea.geometry for altitudearea in new_altitudeareas),
|
||||
crop_to.intersection(new_walls_geoms.buffer(1)),
|
||||
*((new_holes_geoms.buffer(1),) if new_holes_geoms else ()),
|
||||
)),
|
||||
|
||||
access_restriction_affected=None,
|
||||
doors_extended=None,
|
||||
faces=None,
|
||||
vertices=None,
|
||||
walls_base=None,
|
||||
walls_bottom=None,
|
||||
walls_extended=None,
|
||||
)
|
||||
|
||||
new_geoms.build_mesh(interpolators.get(render_level.pk) if level.pk == render_level.pk else None)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue