introducing short walls, so walls stay below stairs from levels on top
This commit is contained in:
parent
fdce9a9ab1
commit
976c49c8ab
2 changed files with 45 additions and 6 deletions
|
@ -166,12 +166,16 @@ class LevelRenderData:
|
||||||
'spaces__obstacles', 'spaces__lineobstacles',
|
'spaces__obstacles', 'spaces__lineobstacles',
|
||||||
'spaces__groups'))
|
'spaces__groups'))
|
||||||
|
|
||||||
single_level_geoms = {level.pk: LevelGeometries.build_for_level(level) for level in levels}
|
single_level_geoms = {}
|
||||||
|
|
||||||
interpolators = {}
|
interpolators = {}
|
||||||
last_interpolator = None
|
last_interpolator = None
|
||||||
|
altitudeareas_above = []
|
||||||
for level in reversed(levels):
|
for level in reversed(levels):
|
||||||
|
single_level_geoms[level.pk] = LevelGeometries.build_for_level(level, altitudeareas_above)
|
||||||
|
|
||||||
if level.on_top_of_id is not None:
|
if level.on_top_of_id is not None:
|
||||||
|
altitudeareas_above.extend(single_level_geoms[level.pk].altitudeareas)
|
||||||
|
altitudeareas_above.sort(key=operator.attrgetter('altitude'))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if last_interpolator is not None:
|
if last_interpolator is not None:
|
||||||
|
@ -239,6 +243,11 @@ class LevelRenderData:
|
||||||
new_geoms = LevelGeometries()
|
new_geoms = LevelGeometries()
|
||||||
new_geoms.doors = crop_to.intersection(old_geoms.doors)
|
new_geoms.doors = crop_to.intersection(old_geoms.doors)
|
||||||
new_geoms.walls = crop_to.intersection(old_geoms.walls)
|
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(
|
||||||
|
(altitude, crop_to.intersection(geom))
|
||||||
|
for altitude, geom in old_geoms.short_walls
|
||||||
|
) if not geom.is_empty)
|
||||||
|
|
||||||
for altitudearea in old_geoms.altitudeareas:
|
for altitudearea in old_geoms.altitudeareas:
|
||||||
new_geometry = crop_to.intersection(altitudearea.geometry)
|
new_geometry = crop_to.intersection(altitudearea.geometry)
|
||||||
|
@ -387,6 +396,8 @@ class LevelGeometries:
|
||||||
self.heightareas = []
|
self.heightareas = []
|
||||||
self.walls = None
|
self.walls = None
|
||||||
self.walls_extended = None
|
self.walls_extended = None
|
||||||
|
self.all_walls = None
|
||||||
|
self.short_walls = []
|
||||||
self.doors = None
|
self.doors = None
|
||||||
self.doors_extended = None
|
self.doors_extended = None
|
||||||
self.holes = None
|
self.holes = None
|
||||||
|
@ -410,7 +421,7 @@ class LevelGeometries:
|
||||||
self.min_altitude = None
|
self.min_altitude = None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def build_for_level(level):
|
def build_for_level(level, altitudeareas_above):
|
||||||
geoms = LevelGeometries()
|
geoms = LevelGeometries()
|
||||||
buildings_geom = unary_union([b.geometry for b in level.buildings.all()])
|
buildings_geom = unary_union([b.geometry for b in level.buildings.all()])
|
||||||
|
|
||||||
|
@ -515,6 +526,19 @@ class LevelGeometries:
|
||||||
|
|
||||||
geoms.walls = buildings_geom.difference(spaces_geom).difference(doors_geom)
|
geoms.walls = buildings_geom.difference(spaces_geom).difference(doors_geom)
|
||||||
|
|
||||||
|
# shorten walls if there are altitudeareas above
|
||||||
|
remaining = geoms.walls
|
||||||
|
for altitudearea in altitudeareas_above:
|
||||||
|
intersection = altitudearea.geometry.intersection(remaining).buffer(0)
|
||||||
|
if intersection.is_empty:
|
||||||
|
continue
|
||||||
|
remaining = remaining.difference(altitudearea.geometry)
|
||||||
|
geoms.short_walls.append((altitudearea.altitude, intersection))
|
||||||
|
geoms.all_walls = geoms.walls
|
||||||
|
geoms.walls = geoms.walls.difference(
|
||||||
|
unary_union(tuple(altitudearea.geometry for altitudearea in altitudeareas_above))
|
||||||
|
)
|
||||||
|
|
||||||
# general level infos
|
# general level infos
|
||||||
geoms.pk = level.pk
|
geoms.pk = level.pk
|
||||||
geoms.on_top_of_id = level.on_top_of_id
|
geoms.on_top_of_id = level.on_top_of_id
|
||||||
|
@ -530,7 +554,8 @@ class LevelGeometries:
|
||||||
def get_geometries(self):
|
def get_geometries(self):
|
||||||
# omit heightareas as these are never drawn
|
# omit heightareas as these are never drawn
|
||||||
return chain(chain(*(area.get_geometries() for area in self.altitudeareas)), (self.walls, self.doors,),
|
return chain(chain(*(area.get_geometries() for area in self.altitudeareas)), (self.walls, self.doors,),
|
||||||
self.restricted_spaces_indoors.values(), self.restricted_spaces_outdoors.values())
|
self.restricted_spaces_indoors.values(), self.restricted_spaces_outdoors.values(),
|
||||||
|
(geom for altitude, geom in self.short_walls))
|
||||||
|
|
||||||
def create_hybrid_geometries(self, face_centers):
|
def create_hybrid_geometries(self, face_centers):
|
||||||
for area in self.altitudeareas:
|
for area in self.altitudeareas:
|
||||||
|
@ -538,6 +563,9 @@ class LevelGeometries:
|
||||||
self.heightareas = tuple((HybridGeometry.create(area, face_centers), height)
|
self.heightareas = tuple((HybridGeometry.create(area, face_centers), height)
|
||||||
for area, height in self.heightareas)
|
for area, height in self.heightareas)
|
||||||
self.walls = HybridGeometry.create(self.walls, face_centers)
|
self.walls = HybridGeometry.create(self.walls, face_centers)
|
||||||
|
self.short_walls = tuple((altitude, HybridGeometry.create(geom, face_centers))
|
||||||
|
for altitude, geom in self.short_walls)
|
||||||
|
self.all_walls = HybridGeometry.create(self.all_walls, face_centers)
|
||||||
self.doors = HybridGeometry.create(self.doors, face_centers)
|
self.doors = HybridGeometry.create(self.doors, face_centers)
|
||||||
self.restricted_spaces_indoors = {key: HybridGeometry.create(geom, face_centers)
|
self.restricted_spaces_indoors = {key: HybridGeometry.create(geom, face_centers)
|
||||||
for key, geom in self.restricted_spaces_indoors.items()}
|
for key, geom in self.restricted_spaces_indoors.items()}
|
||||||
|
@ -654,13 +682,19 @@ class LevelGeometries:
|
||||||
area.remove_faces(reduce(operator.or_, self.walls.faces, set()))
|
area.remove_faces(reduce(operator.or_, self.walls.faces, set()))
|
||||||
|
|
||||||
# create polyhedrons
|
# create polyhedrons
|
||||||
self.walls_base = HybridGeometry(self.walls.geom, self.walls.faces)
|
self.walls_base = HybridGeometry(self.all_walls.geom, self.all_walls.faces)
|
||||||
self.walls_bottom = HybridGeometry(self.walls.geom, self.walls.faces)
|
self.walls_bottom = HybridGeometry(self.all_walls.geom, self.all_walls.faces)
|
||||||
self.walls_extended = HybridGeometry(self.walls.geom, self.walls.faces)
|
self.walls_extended = HybridGeometry(self.walls.geom, self.walls.faces)
|
||||||
self.walls.build_polyhedron(self._create_polyhedron,
|
self.walls.build_polyhedron(self._create_polyhedron,
|
||||||
lower=vertex_altitudes - int(0.7 * 1000),
|
lower=vertex_altitudes - int(0.7 * 1000),
|
||||||
upper=vertex_wall_heights)
|
upper=vertex_wall_heights)
|
||||||
|
|
||||||
|
for altitude, geom in self.short_walls:
|
||||||
|
geom.build_polyhedron(self._create_polyhedron,
|
||||||
|
lower=vertex_altitudes - int(0.7 * 1000),
|
||||||
|
upper=altitude - int(0.7 * 1000))
|
||||||
|
self.short_walls = tuple(geom for altitude, geom in self.short_walls)
|
||||||
|
|
||||||
for key, geometry in self.restricted_spaces_indoors.items():
|
for key, geometry in self.restricted_spaces_indoors.items():
|
||||||
geometry.crop_ids = frozenset(('in:%s' % key, ))
|
geometry.crop_ids = frozenset(('in:%s' % key, ))
|
||||||
for key, geometry in self.restricted_spaces_outdoors.items():
|
for key, geometry in self.restricted_spaces_outdoors.items():
|
||||||
|
@ -706,6 +740,7 @@ class LevelGeometries:
|
||||||
self.walls_bottom.build_polyhedron(self._create_polyhedron, lower=0, upper=1, top=False)
|
self.walls_bottom.build_polyhedron(self._create_polyhedron, lower=0, upper=1, top=False)
|
||||||
|
|
||||||
# unset heightareas, they are no loinger needed
|
# unset heightareas, they are no loinger needed
|
||||||
|
self.all_walls = None
|
||||||
self.heightareas = None
|
self.heightareas = None
|
||||||
self.vertices = None
|
self.vertices = None
|
||||||
self.faces = None
|
self.faces = None
|
||||||
|
|
|
@ -147,6 +147,10 @@ class MapRenderer:
|
||||||
top=not walls_extended),
|
top=not walls_extended),
|
||||||
height=geoms.default_height, fill=FillAttribs('#aaaaaa'), category='walls')
|
height=geoms.default_height, fill=FillAttribs('#aaaaaa'), category='walls')
|
||||||
|
|
||||||
|
for short_wall in geoms.short_walls:
|
||||||
|
engine.add_geometry(short_wall.filter(bottom=not not_full_levels),
|
||||||
|
height=geoms.default_height, fill=FillAttribs('#aaaaaa'), category='walls')
|
||||||
|
|
||||||
if walls_extended:
|
if walls_extended:
|
||||||
engine.add_geometry(geoms.walls_extended, fill=FillAttribs('#aaaaaa'), category='walls')
|
engine.add_geometry(geoms.walls_extended, fill=FillAttribs('#aaaaaa'), category='walls')
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue