OpenDroneMap-ODM/stages/odm_meshing.py

68 wiersze
2.8 KiB
Python

import os, math
from opendm import log
from opendm import io
from opendm import system
from opendm import context
from opendm import mesh
from opendm import gsd
from opendm import types
from opendm.dem import commands
class ODMeshingStage(types.ODM_Stage):
def process(self, args, outputs):
tree = outputs['tree']
reconstruction = outputs['reconstruction']
# define paths and create working directories
system.mkdir_p(tree.odm_meshing)
# Create full 3D model unless --skip-3dmodel is set
if not args.skip_3dmodel:
if not io.file_exists(tree.odm_mesh) or self.rerun():
log.ODM_INFO('Writing ODM Mesh file in: %s' % tree.odm_mesh)
mesh.screened_poisson_reconstruction(tree.filtered_point_cloud,
tree.odm_mesh,
depth=self.params.get('oct_tree'),
samples=self.params.get('samples'),
maxVertexCount=self.params.get('max_vertex'),
pointWeight=self.params.get('point_weight'),
threads=max(1, self.params.get('max_concurrency') - 1)), # poissonrecon can get stuck on some machines if --threads == all cores
else:
log.ODM_WARNING('Found a valid ODM Mesh file in: %s' %
tree.odm_mesh)
self.update_progress(50)
# Always generate a 2.5D mesh
# unless --use-3dmesh is set.
if not args.use_3dmesh:
if not io.file_exists(tree.odm_25dmesh) or self.rerun():
log.ODM_INFO('Writing ODM 2.5D Mesh file in: %s' % tree.odm_25dmesh)
multiplier = math.pi / 2.0
radius_steps = commands.get_dem_radius_steps(tree.filtered_point_cloud_stats, 3, args.orthophoto_resolution, multiplier=multiplier)
dsm_resolution = radius_steps[0] / multiplier
log.ODM_INFO('ODM 2.5D DSM resolution: %s' % dsm_resolution)
if args.fast_orthophoto:
dsm_resolution *= 8.0
mesh.create_25dmesh(tree.filtered_point_cloud, tree.odm_25dmesh,
radius_steps,
dsm_resolution=dsm_resolution,
depth=self.params.get('oct_tree'),
maxVertexCount=self.params.get('max_vertex'),
samples=self.params.get('samples'),
available_cores=args.max_concurrency,
method='poisson' if args.fast_orthophoto else 'gridded',
smooth_dsm=True,
max_tiles=None if reconstruction.has_geotagged_photos() else math.ceil(len(reconstruction.photos) / 2))
else:
log.ODM_WARNING('Found a valid ODM 2.5D Mesh file in: %s' %
tree.odm_25dmesh)