diff --git a/.idea/libs.iml b/.idea/libs.iml index 7d99385a..c268a131 100644 --- a/.idea/libs.iml +++ b/.idea/libs.iml @@ -6,7 +6,7 @@ - + diff --git a/exports/exports_factory.py b/exports/exports_factory.py index 04f2f9be..6a9d0216 100644 --- a/exports/exports_factory.py +++ b/exports/exports_factory.py @@ -7,6 +7,7 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc from exports.formats.stl import Stl from exports.formats.obj import Obj + class ExportsFactory: """ Exports factory class @@ -38,7 +39,7 @@ class ExportsFactory: Export the city geometry to obj :return: None """ - return Obj(self._city, self._path) + return Obj(self._city, self._path).to_ground_points() @property def _idf(self): diff --git a/exports/formats/obj.py b/exports/formats/obj.py index 56e30706..f3f572ed 100644 --- a/exports/formats/obj.py +++ b/exports/formats/obj.py @@ -1,5 +1,25 @@ from exports.formats.triangular import Triangular +from pathlib import Path +from imports.geometry_factory import GeometryFactory +import trimesh.exchange.obj +from trimesh import Trimesh + class Obj(Triangular): def __init__(self, city, path): super().__init__(city, path, 'obj') + + def to_ground_points(self): + reference_coordinates = self._city.lower_corner + file_name_in = self._city.name + '.' + self._triangular_format + file_name_out = self._city.name + '_ground.' + self._triangular_format + file_path_in = (Path(self._path).resolve() / file_name_in).resolve() + file_path_out = (Path(self._path).resolve() / file_name_out).resolve() + scene_dic = GeometryFactory('obj', file_path_in).scene + for vertex in scene_dic['vertices']: + for i in range(0, 3): + vertex[i] -= reference_coordinates[i] + scene = Trimesh(vertices=scene_dic['vertices'], faces=scene_dic['faces']) + obj_file = trimesh.exchange.obj.export_obj(scene) + with open(file_path_out, 'w') as file: + file.write(obj_file) diff --git a/exports/formats/stl.py b/exports/formats/stl.py index 915d455d..984c207a 100644 --- a/exports/formats/stl.py +++ b/exports/formats/stl.py @@ -1,5 +1,6 @@ from exports.formats.triangular import Triangular + class Stl(Triangular): def __init__(self, city, path): super().__init__(city, path, 'stl') diff --git a/exports/formats/triangular.py b/exports/formats/triangular.py index de5b9ec4..8a7b9dda 100644 --- a/exports/formats/triangular.py +++ b/exports/formats/triangular.py @@ -1,6 +1,7 @@ from pathlib import Path from trimesh import Trimesh + class Triangular: def __init__(self, city, path, triangular_format): self._city = city diff --git a/imports/geometry_factory.py b/imports/geometry_factory.py index a9c55d85..447a29fe 100644 --- a/imports/geometry_factory.py +++ b/imports/geometry_factory.py @@ -7,6 +7,7 @@ from city_model_structure.city import City from city_model_structure.city_object import CityObject from imports.geometry_feeders.city_gml import CityGml from imports.geometry_feeders.osm_subway import OsmSubway +from imports.geometry_feeders.obj import Obj class GeometryFactory: @@ -25,6 +26,10 @@ class GeometryFactory: def _stl(self): raise Exception('Not implemented') + @property + def _obj(self): + return Obj(self._path).scene + @property def _geojson(self): raise Exception('Not implemented') @@ -41,6 +46,14 @@ class GeometryFactory: """ return getattr(self, self._file_type, lambda: None) + @property + def scene(self): + """ + Load the city model structure from a geometry source + :return: Trimesh + """ + return getattr(self, self._file_type, lambda: None) + @property def _city_debug(self): return CityGml(self._path).city diff --git a/imports/geometry_feeders/obj.py b/imports/geometry_feeders/obj.py new file mode 100644 index 00000000..fc82847a --- /dev/null +++ b/imports/geometry_feeders/obj.py @@ -0,0 +1,21 @@ +""" +Obj module parses obj files and import the geometry into the city model structure +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Pilar Monsalvete Álvarez de Uribarri pilar.monsalvete@concordia.ca +""" +import trimesh.exchange.obj + + +class Obj: + """ + Obj class + """ + def __init__(self, path): + self._city = None + with open(path, 'r') as file: + self._scene = trimesh.exchange.obj.load_obj(file) + # todo: review class trimesh.exchange.load that returns Trimesh or Trimesh.scene + + @property + def scene(self) -> dict: + return self._scene diff --git a/requirements.txt b/requirements.txt index 24f9d4f4..638c0a1d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,11 @@ xmltodict~=0.12.0 numpy~=1.20.1 -trimesh~=3.9.8 +trimesh~=3.9.9 pyproj~=3.0.1 pandas~=1.2.3 requests~=2.25.1 esoreader~=1.2.3 geomeppy~=0.11.8 open3d~=0.12.0 -pathlib~=1.0.1 \ No newline at end of file +pathlib~=1.0.1 +PyWavefront~=1.3.3 \ No newline at end of file diff --git a/tests/test_exports.py b/tests/test_exports.py index 99ddb926..19ce1bb0 100644 --- a/tests/test_exports.py +++ b/tests/test_exports.py @@ -9,6 +9,7 @@ from unittest import TestCase from imports.geometry_factory import GeometryFactory from exports.exports_factory import ExportsFactory + class TestExports(TestCase): """ TestGeometryFactory TestCase 1