more comments \o/

This commit is contained in:
Laura Klünder 2017-12-14 23:57:59 +01:00
parent 89ea3fec16
commit 93cd4f0e77
5 changed files with 53 additions and 0 deletions

View file

@ -109,6 +109,7 @@ class AccessPermissionForm(Form):
for restriction in self.cleaned_data['access_restrictions']:
expire_date = self.cleaned_data['expires']
author_expire_date = self.author_access_permissions.get(restriction.pk)
# make sure that each permission is not granted for a longer time than the author has it
if author_expire_date is not None:
expire_date = author_expire_date if expire_date is None else min(expire_date, author_expire_date)
restrictions.append(AccessPermissionTokenItem(pk=restriction.pk, expire_date=expire_date,

View file

@ -4,6 +4,9 @@ from c3nav.control.models import UserPermissions
class UserPermissionsMiddleware:
"""
This middleware adds request.user_permissions to get the UserPermissions for the current request/user.
"""
def __init__(self, get_response):
self.get_response = get_response

View file

@ -28,6 +28,14 @@ def hybrid_union(geoms):
class HybridGeometry:
"""
A geometry containing a mesh as well as a shapely geometry,
so it can be used for different kinds of render engines.
This object can be in 2 states:
- 2d mesh state where faces refers to indizes of faces from an external list
- 3d mesh state where faces refers to Mesh instances
"""
__slots__ = ('geom', 'faces', 'crop_ids', 'add_faces')
def __init__(self, geom, faces, crop_ids=frozenset(), add_faces=None):
@ -38,6 +46,9 @@ class HybridGeometry:
@classmethod
def create(cls, geom, face_centers):
"""
Create from existing facets and just select the ones that lie inside this polygon.
"""
if isinstance(geom, (LineString, MultiLineString)):
return HybridGeometry(geom, set())
faces = tuple(
@ -48,6 +59,9 @@ class HybridGeometry:
@classmethod
def create_full(cls, geom, vertices_offset, faces_offset):
"""
Create by triangulating a polygon and adding the resulting facets to the total list.
"""
if isinstance(geom, (LineString, MultiLineString)):
return HybridGeometry(geom, set()), np.empty((0, 2), dtype=np.int32), np.empty((0, 3), dtype=np.uint32)
@ -85,6 +99,9 @@ class HybridGeometry:
crop_ids=self.crop_ids - other.crop_ids)
def fit(self, scale, offset):
"""
Fit this object (when it has minz=0 maxz=1) into a given minz, maxz range.
"""
offset = np.array((0, 0, offset))
scale = np.array((1, 1, scale))
return HybridGeometry(geom=self.geom, crop_ids=self.crop_ids,
@ -93,6 +110,9 @@ class HybridGeometry:
for crop_id, faces in self.add_faces})
def filter(self, **kwargs):
"""
Remove top, bottom or side facets.
"""
return HybridGeometry(geom=self.geom, crop_ids=self.crop_ids,
faces=tuple(mesh.filter(**kwargs) for mesh in self.faces),
add_faces={crop_id: tuple(mesh.filter(**kwargs) for mesh in faces)
@ -106,6 +126,10 @@ class HybridGeometry:
return not self.faces and not any(self.add_faces.values())
def build_polyhedron(self, create_polyhedron, crops=None, **kwargs):
"""
Create polyhedron using an externel function from this object,
which means converting it from a flat mesh to a 3d mesh state.
"""
remaining_faces = self.faces
for crop, prep in crops or ():
if prep.intersects(self.geom):

View file

@ -20,6 +20,9 @@ empty_geometry_collection = GeometryCollection()
class LevelGeometries:
"""
Store geometries for a Level.
"""
def __init__(self):
self.altitudeareas = []
self.heightareas = []
@ -244,6 +247,9 @@ class LevelGeometries:
return item[0].get_altitudes(self.vertices[i_vertices]) - int(0.7 * 1000)
def _build_vertex_values(self, items, area_func, value_func):
"""
Interpolate vertice with known altitudes to get altitudes for the remaining ones.
"""
vertex_values = np.empty(self.vertices.shape[:1], dtype=np.int32)
vertex_value_mask = np.full(self.vertices.shape[:1], fill_value=False, dtype=np.bool)
@ -262,9 +268,15 @@ class LevelGeometries:
return vertex_values
def _filter_faces(self, faces):
"""
Filter faces so that no zero area faces remain.
"""
return faces[np.all(np.any(faces[:, (0, 1, 2), :]-faces[:, (2, 0, 1), :], axis=2), axis=1)]
def _create_polyhedron(self, faces, lower, upper, top=True, sides=True, bottom=True):
"""
Callback function for HybridGeometry.create_polyhedron()
"""
if not any(faces):
return ()
@ -351,6 +363,11 @@ class LevelGeometries:
return tuple((Mesh(top, sides, bottom),))
def build_mesh(self, interpolator=None):
"""
Build the entire mesh
"""
# first we triangulate most polygons in one go
rings = tuple(chain(*(get_rings(geom) for geom in self.get_geometries())))
self.vertices, self.faces = triangulate_rings(rings)
self.create_hybrid_geometries(face_centers=self.vertices[self.faces].sum(axis=1) / 3000)
@ -369,6 +386,7 @@ class LevelGeometries:
area.remove_faces(reduce(operator.or_, self.walls.faces, set()))
# create polyhedrons
# we build the walls to often so we can extend them to create leveled 3d model bases.
self.walls_base = HybridGeometry(self.all_walls.geom, self.all_walls.faces)
self.walls_bottom = HybridGeometry(self.all_walls.geom, self.all_walls.faces)
self.walls_extended = HybridGeometry(self.walls.geom, self.walls.faces)
@ -384,6 +402,7 @@ class LevelGeometries:
value_func=self._get_short_wall_vertex_values))
self.short_walls = tuple(geom for altitude, geom in self.short_walls)
# make sure we are able to crop spaces when a access restriction is apply
for key, geometry in self.restricted_spaces_indoors.items():
geometry.crop_ids = frozenset(('in:%s' % key, ))
for key, geometry in self.restricted_spaces_outdoors.items():

View file

@ -4,6 +4,9 @@ import numpy as np
class Mesh(namedtuple('Mesh', ('top', 'sides', 'bottom'))):
"""
Store a mesh, divided into top, bottom and side facets.
"""
__slots__ = ()
empty_faces = np.empty((0, 3, 3)).astype(np.int32)
@ -21,6 +24,9 @@ class Mesh(namedtuple('Mesh', ('top', 'sides', 'bottom'))):
np.rint(self.bottom+other).astype(np.int32))
def filter(self, top=True, sides=True, bottom=True):
"""
Remove top, bottom or side facets.
"""
return Mesh(top=self.top if top else self.empty_faces,
sides=self.sides if sides else self.empty_faces,
bottom=self.bottom if bottom else self.empty_faces)