hub/imports/geometry/obj.py

85 lines
2.8 KiB
Python
Raw Normal View History

2021-03-16 16:58:52 -04:00
"""
Obj module parses obj files and import the geometry into the city model structure
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
2021-03-16 16:58:52 -04:00
"""
2021-04-07 14:20:13 -04:00
import trimesh.exchange.load
from trimesh import Scene
import trimesh.geometry
from city_model_structure.city import City
from city_model_structure.building import Building
from city_model_structure.building_demand.surface import Surface
from city_model_structure.attributes.polygon import Polygon
2021-03-16 16:58:52 -04:00
class Obj:
"""
Obj class
"""
def __init__(self, path):
self._city = None
with open(path, 'r') as file:
2021-04-07 14:20:13 -04:00
self._scene = trimesh.exchange.load.load(file, file_type='obj', force='scene')
self._corners = self._scene.bounds_corners
2021-11-16 07:57:47 -05:00
_bound_corner_min = None
_bound_corner_max = None
2021-04-07 14:20:13 -04:00
for corner in self._corners:
if _bound_corner_min is None:
_bound_corner_min = corner
elif _bound_corner_max is None:
_bound_corner_max = corner
else:
_bound_corner_min[0] = min(_bound_corner_min[0], corner[0])
_bound_corner_min[1] = min(_bound_corner_min[1], corner[1])
_bound_corner_min[2] = min(_bound_corner_min[2], corner[2])
_bound_corner_max[0] = max(_bound_corner_max[0], corner[0])
_bound_corner_max[1] = max(_bound_corner_max[1], corner[1])
_bound_corner_max[2] = max(_bound_corner_max[2], corner[2])
self._lower_corner = _bound_corner_min
self._upper_corner = _bound_corner_max
2021-03-16 16:58:52 -04:00
@property
2021-04-07 14:20:13 -04:00
def scene(self) -> Scene:
2021-08-27 12:51:30 -04:00
"""
Get obj scene
2021-08-27 12:51:30 -04:00
"""
2021-03-16 16:58:52 -04:00
return self._scene
@property
2021-04-07 14:20:13 -04:00
def city(self) -> City:
2021-08-27 12:51:30 -04:00
"""
Get city out of an obj file
2021-08-27 12:51:30 -04:00
"""
if self._city is None:
2021-04-07 14:20:13 -04:00
# todo: refactor this method to clearly choose the obj type
# todo: where do we get this information from?
srs_name = 'EPSG:26911'
2021-04-07 14:20:13 -04:00
self._city = City(self._lower_corner, self._upper_corner, srs_name)
scene = self.scene.geometry
keys = scene.keys()
lod = 1
2021-04-07 14:20:13 -04:00
for key in keys:
name = key
# todo: where do we get this information from?
2021-04-07 14:20:13 -04:00
year_of_construction = 0
function = ''
obj = scene[key]
surfaces = []
for face in obj.faces:
# todo: review for obj with windows
points = []
for vertex_index in face:
points.append(obj.vertices[vertex_index])
solid_polygon = Polygon(points)
perimeter_polygon = solid_polygon
surface = Surface(solid_polygon, perimeter_polygon)
surfaces.append(surface)
building = Building(name, surfaces, year_of_construction, function, self._lower_corner, terrains=None)
2021-04-07 14:31:16 -04:00
self._city.add_city_object(building)
self._city.level_of_detail.geometry = lod
return self._city