export to obj partial implementation
This commit is contained in:
parent
20b88fbccb
commit
fdef2152d9
|
@ -71,7 +71,7 @@ class ExportsFactory:
|
||||||
Export the city geometry to obj with grounded coordinates
|
Export the city geometry to obj with grounded coordinates
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
return Obj(self._city, self._path).to_ground_points()
|
return Obj(self._city, self._path)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _sra(self):
|
def _sra(self):
|
||||||
|
|
|
@ -11,24 +11,55 @@ from hub.exports.formats.triangular import Triangular
|
||||||
from hub.imports.geometry_factory import GeometryFactory
|
from hub.imports.geometry_factory import GeometryFactory
|
||||||
|
|
||||||
|
|
||||||
class Obj(Triangular):
|
class Obj:
|
||||||
"""
|
"""
|
||||||
Export to obj format
|
Export to obj format
|
||||||
"""
|
"""
|
||||||
def __init__(self, city, path):
|
def __init__(self, city, path):
|
||||||
super().__init__(city, path, 'obj')
|
self._city = city
|
||||||
|
self._path = path
|
||||||
|
self._export()
|
||||||
|
|
||||||
|
def _to_vertex(self, coordinate):
|
||||||
|
x = coordinate[0] - self._city.lower_corner[0]
|
||||||
|
y = coordinate[1] - self._city.lower_corner[1]
|
||||||
|
z = coordinate[2] - self._city.lower_corner[2]
|
||||||
|
return f'v {x} {y} {z}\n'
|
||||||
|
|
||||||
|
def _export(self):
|
||||||
|
if self._city.name is None:
|
||||||
|
self._city.name = 'unknown_city'
|
||||||
|
file_name = self._city.name + '.obj'
|
||||||
|
file_path = (Path(self._path).resolve() / file_name).resolve()
|
||||||
|
vertices = {}
|
||||||
|
with open(file_path, 'w') as obj:
|
||||||
|
obj.write("# cerc-hub export\n")
|
||||||
|
vertex_index = 0
|
||||||
|
faces = []
|
||||||
|
for building in self._city.buildings:
|
||||||
|
obj.write(f'# building {building.name}\n')
|
||||||
|
for surface in building.surfaces:
|
||||||
|
obj.write(f'# surface {surface.name}\n')
|
||||||
|
face = 'f '
|
||||||
|
len_ = len(surface.perimeter_polygon.coordinates)
|
||||||
|
if len_ > 40:
|
||||||
|
print(len_, building.name)
|
||||||
|
for coordinate in surface.perimeter_polygon.coordinates:
|
||||||
|
|
||||||
|
vertex = self._to_vertex(coordinate)
|
||||||
|
if vertex not in vertices.keys():
|
||||||
|
vertex_index += 1
|
||||||
|
vertices[vertex] = vertex_index
|
||||||
|
current = vertex_index
|
||||||
|
obj.write(vertex)
|
||||||
|
else:
|
||||||
|
current = vertices[vertex]
|
||||||
|
|
||||||
|
face = f'{face} {current}'
|
||||||
|
|
||||||
|
faces.append(f'{face} {face.split(" ")[1]}\n')
|
||||||
|
obj.writelines(faces)
|
||||||
|
faces = []
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def to_ground_points(self):
|
|
||||||
"""
|
|
||||||
Move closer to the origin
|
|
||||||
"""
|
|
||||||
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()
|
|
||||||
obj = GeometryFactory('obj', path=file_path_in)
|
|
||||||
scene = obj.scene
|
|
||||||
scene.rezero()
|
|
||||||
obj_file = trimesh.exchange.obj.export_obj(scene)
|
|
||||||
with open(file_path_out, 'w') as file:
|
|
||||||
file.write(obj_file)
|
|
||||||
|
|
|
@ -231,7 +231,7 @@ class Geojson:
|
||||||
self._city.add_city_object(building)
|
self._city.add_city_object(building)
|
||||||
self._city.level_of_detail.geometry = lod
|
self._city.level_of_detail.geometry = lod
|
||||||
if lod == 1:
|
if lod == 1:
|
||||||
lines_information = GeometryHelper.city_mapping(self._city, plot=True)
|
lines_information = GeometryHelper.city_mapping(self._city)
|
||||||
self._store_shared_percentage_to_walls(self._city, lines_information)
|
self._store_shared_percentage_to_walls(self._city, lines_information)
|
||||||
if len(missing_functions) > 0:
|
if len(missing_functions) > 0:
|
||||||
print(f'There are unknown functions {missing_functions}')
|
print(f'There are unknown functions {missing_functions}')
|
||||||
|
|
|
@ -138,9 +138,8 @@ class TestGeometryFactory(TestCase):
|
||||||
year_of_construction_field='ANNEE_CONS',
|
year_of_construction_field='ANNEE_CONS',
|
||||||
function_field='CODE_UTILI')
|
function_field='CODE_UTILI')
|
||||||
|
|
||||||
for building in city.buildings:
|
hub.exports.exports_factory.ExportsFactory('obj', city, self._output_path).export()
|
||||||
print(building.volume)
|
self.assertEqual(195, len(city.buildings), 'wrong number of buildings')
|
||||||
self.assertEqual(207, len(city.buildings), 'wrong number of buildings')
|
|
||||||
self._check_buildings(city)
|
self._check_buildings(city)
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for wall in building.walls:
|
for wall in building.walls:
|
||||||
|
@ -161,7 +160,7 @@ class TestGeometryFactory(TestCase):
|
||||||
year_of_construction_field='ANNEE_CONS',
|
year_of_construction_field='ANNEE_CONS',
|
||||||
function_field='LIBELLE_UT')
|
function_field='LIBELLE_UT')
|
||||||
info_lod1 = GeometryHelper.city_mapping(city, plot=False)
|
info_lod1 = GeometryHelper.city_mapping(city, plot=False)
|
||||||
|
hub.exports.exports_factory.ExportsFactory('obj', city, self._output_path).export()
|
||||||
self.assertEqual(info_lod0, info_lod1)
|
self.assertEqual(info_lod0, info_lod1)
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
self.assertEqual(2, len(building.neighbours))
|
self.assertEqual(2, len(building.neighbours))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user