significantly simpler cut

This commit is contained in:
Laura Klünder 2018-12-05 22:58:24 +01:00
parent 4dbd59b1bd
commit f7507cabe8

View file

@ -1,7 +1,5 @@
import re
from itertools import chain
import numpy as np
from shapely import prepared
from shapely.affinity import scale
from shapely.geometry import JOIN_STYLE, LineString, Point
@ -9,9 +7,8 @@ from shapely.ops import unary_union
from c3nav.mapdata.render.engines import register_engine
from c3nav.mapdata.render.engines.base3d import Base3DEngine
from c3nav.mapdata.render.utils import get_full_levels, get_min_altitude
from c3nav.mapdata.render.utils import get_full_levels
from c3nav.mapdata.utils.geometry import assert_multipolygon
from c3nav.mapdata.utils.mesh import triangulate_gapless_mesh_from_polygons
@register_engine
@ -208,15 +205,33 @@ class BlenderEngine(Base3DEngine):
def custom_render(self, level_render_data, access_permissions):
levels = get_full_levels(level_render_data)
min_altitude = get_min_altitude(levels, default=level_render_data.base_altitude)
vertices, faces = triangulate_gapless_mesh_from_polygons([self.buffered_bbox])
current_min_z = min_altitude-700
current_max_z = min_altitude-700
vertices = np.hstack((vertices, np.full((vertices.shape[0], 1), current_min_z)))
self._add_mesh_plane('Bottom mesh', vertices / 1000, faces)
buildings = None
last_lower_bound = None
for geoms in reversed(levels):
if geoms.on_top_of_id is not None:
continue
altitudes = [geoms.base_altitude]
for altitudearea in geoms.altitudeareas:
altitudes.append(altitudearea.altitude)
if altitudearea.altitude2 is not None:
altitudes.append(altitudearea.altitude2)
if last_lower_bound is None:
altitude = max(altitudes)
height = max((height for (geometry, height) in geoms.heightareas), default=geoms.default_height)
last_lower_bound = altitude+height
geoms.upper_bound = last_lower_bound
geoms.lower_bound = min(altitudes)-700
last_lower_bound = geoms.lower_bound
for geoms in levels:
if geoms.on_top_of_id is not None:
continue
# hide indoor and outdoor rooms if their access restriction was not unlocked
restricted_spaces_indoors = unary_union(
tuple(area.geom for access_restriction, area in geoms.restricted_spaces_indoors.items()
@ -241,49 +256,12 @@ class BlenderEngine(Base3DEngine):
new_heightareas.append((geometry, geometry_prep, height))
geoms.heightareas = new_heightareas
# create upper bounds for this level's walls (next mesh plane)
vertices, faces = triangulate_gapless_mesh_from_polygons(
[self.buffered_bbox] + assert_multipolygon(geoms.buildings) +
list(chain(*(assert_multipolygon(altitudearea.geometry) for altitudearea in geoms.altitudeareas)))
)
altitudes = []
for x, y in vertices:
point = Point(x/1000, y/1000)
xy = np.array((x, y))
if geoms.on_top_of_id is None:
buildings = geoms.buildings
matching_altitudeareas = [altitudearea for altitudearea in geoms.altitudeareas
if altitudearea.geometry_prep.intersects(point)]
if not matching_altitudeareas:
altitudearea_distances = tuple((altitudearea.geometry.distance(point), altitudearea)
for altitudearea in geoms.altitudeareas)
min_distance = min(distance for distance, altitudearea in altitudearea_distances)
matching_altitudeareas = [altitudearea for distance, altitudearea in altitudearea_distances
if distance == min_distance]
altitude = max(altitudearea.get_altitudes(xy)[0] for altitudearea in matching_altitudeareas)
matching_heights = [height for geom, geom_prep, height in geoms.heightareas
if geom_prep.intersects(point)]
if not matching_heights:
heightarea_distances = tuple((geom.distance(point), i)
for i, (geom, geom_prep, height) in enumerate(geoms.heightareas))
min_distance = min(distance for distance, i in heightarea_distances)
matching_heights = [geoms.heightareas[i][2] for distance, i in heightarea_distances
if distance == min_distance]
height = max(matching_heights)
altitudes.append(altitude+height)
last_min_z = current_min_z
last_max_z = current_max_z # noqa
current_min_z = min(altitudes) # noqa
current_max_z = max(altitudes)
vertices = np.hstack((vertices, np.array(altitudes).reshape((vertices.shape[0], 1))))
self._add_mesh_plane('Level %s top mesh plane' % geoms.short_label, vertices / 1000, faces)
self._add_polygon('Level %s' % geoms.short_label, geoms.buildings,
last_min_z-1000, current_max_z+1000)
self._add_polygon('Level %s' % geoms.short_label, buildings,
geoms.lower_bound, geoms.upper_bound)
self._set_last_polygon_to_main()
self._cut_last_poly_with_mesh_planes(last_min_z-1000, current_max_z+1000)
for altitudearea in geoms.altitudeareas:
name = 'Level %s Altitudearea %s' % (geoms.short_label, altitudearea.altitude)
@ -291,7 +269,7 @@ class BlenderEngine(Base3DEngine):
if altitudearea.altitude2 is not None:
self._debug('slope start')
min_slope_altitude = min(altitudearea.altitude, altitudearea.altitude2)
self._add_polygon(name, buffered_geom, min_slope_altitude-10, current_max_z+1000)
self._add_polygon(name, buffered_geom, min_slope_altitude-10, geoms.upper_bound+1000)
bounds = buffered_geom.bounds
self._add_slope(bounds, altitudearea.altitude-10, altitudearea.altitude2-10,
altitudearea.point1, altitudearea.point2, bottom=True)
@ -301,11 +279,9 @@ class BlenderEngine(Base3DEngine):
self._debug('slope end')
else:
self._add_polygon(name, buffered_geom,
altitudearea.altitude, current_max_z+1000)
altitudearea.altitude, geoms.upper_bound+1000)
self._subtract_last_polygon_from_main()
break
self._add_python('''
if last_mesh_plane:
delete_object(last_mesh_plane)