Exemple #1
0
def mesh_3d(odm_mesh_folder, odm_mesh_ply, filter_point_cloud_path,
            max_concurrency):
    if not io.file_exists(odm_mesh_ply):
        log.ODM_INFO('Writing ODM Mesh file in: %s' % odm_mesh_ply)
        oct_tree = 10
        samples = 1.0
        max_vertex = 200000
        point_weight = 4
        verbose = False
        mesh.screened_poisson_reconstruction(
            filter_point_cloud_path,
            odm_mesh_ply,
            depth=oct_tree,
            samples=samples,
            maxVertexCount=max_vertex,
            pointWeight=point_weight,
            threads=max(
                1, max_concurrency - 1
            ),  # poissonrecon can get stuck on some machines if --threads == all cores
            verbose=verbose)

    else:
        log.ODM_WARNING('Found a valid ODM Mesh file in: %s' % odm_mesh_ply)
    def process(self, inputs, outputs):

        # Benchmarking
        start_time = system.now_raw()

        log.ODM_INFO('Running ODM Meshing Cell')

        # get inputs
        args = inputs.args
        tree = inputs.tree
        reconstruction = inputs.reconstruction

        # define paths and create working directories
        system.mkdir_p(tree.odm_meshing)

        # check if we rerun cell or not
        rerun_cell = (args.rerun is not None and
                      args.rerun == 'odm_meshing') or \
                     (args.rerun_all) or \
                     (args.rerun_from is not None and
                      'odm_meshing' in args.rerun_from)

        infile = tree.smvs_model
        if args.fast_orthophoto:
            infile = os.path.join(tree.opensfm, 'reconstruction.ply')
        elif args.use_opensfm_dense:
            infile = tree.opensfm_model

        # Create full 3D model unless --skip-3dmodel is set
        if not args.skip_3dmodel:
            if not io.file_exists(tree.odm_mesh) or rerun_cell:
                log.ODM_DEBUG('Writing ODM Mesh file in: %s' % tree.odm_mesh)

                mesh.screened_poisson_reconstruction(
                    infile,
                    tree.odm_mesh,
                    depth=self.params.oct_tree,
                    samples=self.params.samples,
                    maxVertexCount=self.params.max_vertex,
                    pointWeight=self.params.point_weight,
                    threads=self.params.max_concurrency,
                    verbose=self.params.verbose)

            else:
                log.ODM_WARNING('Found a valid ODM Mesh file in: %s' %
                                tree.odm_mesh)

        # 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 rerun_cell:

                log.ODM_DEBUG('Writing ODM 2.5D Mesh file in: %s' %
                              tree.odm_25dmesh)
                dsm_resolution = gsd.cap_resolution(
                    args.orthophoto_resolution,
                    tree.opensfm_reconstruction,
                    ignore_gsd=args.ignore_gsd) / 100.0

                # Create reference DSM at half ortho resolution
                dsm_resolution *= 2

                # Sparse point clouds benefits from using
                # a larger resolution value (more radius interolation, less holes)
                if args.fast_orthophoto:
                    dsm_resolution *= 2

                mesh.create_25dmesh(infile,
                                    tree.odm_25dmesh,
                                    dsm_resolution=dsm_resolution,
                                    depth=self.params.oct_tree,
                                    maxVertexCount=self.params.max_vertex,
                                    samples=self.params.samples,
                                    verbose=self.params.verbose,
                                    max_workers=args.max_concurrency)
            else:
                log.ODM_WARNING('Found a valid ODM 2.5D Mesh file in: %s' %
                                tree.odm_25dmesh)

        outputs.reconstruction = reconstruction

        if args.time:
            system.benchmark(start_time, tree.benchmarking, 'Meshing')

        log.ODM_INFO('Running ODM Meshing Cell - Finished')
        return ecto.OK if args.end_with != 'odm_meshing' else ecto.QUIT
def mesh_3d(args, odm_mesh_folder, odm_mesh_ply, filter_point_cloud_path,
            max_concurrency, reconstruction, current_path):
    oct_tree = 10
    samples = 1.0
    max_vertex = 200000
    point_weight = 4
    verbose = False
    args['fast_orthophoto'] = True

    if args['use_3dmesh']:
        if not io.file_exists(odm_mesh_ply):
            log.ODM_INFO('Writing ODM Mesh file in: %s' % odm_mesh_ply)

            mesh.screened_poisson_reconstruction(
                filter_point_cloud_path,
                odm_mesh_ply,
                depth=oct_tree,
                samples=samples,
                maxVertexCount=max_vertex,
                pointWeight=point_weight,
                threads=max(
                    1, max_concurrency - 1
                ),  # poissonrecon can get stuck on some machines if --threads == all cores
                verbose=verbose)

        else:
            log.ODM_WARNING('Found a valid ODM Mesh file in: %s' %
                            odm_mesh_ply)

    if not args['use_3dmesh']:
        if not io.file_exists(odm_mesh_ply):
            opensfm_reconstruction = io.join_paths(current_path,
                                                   'reconstruction.json')
            reconstruction = reconstruction

            log.ODM_INFO('Writing ODM 2.5D Mesh file in: %s' % odm_mesh_ply)
            ortho_resolution = gsd.cap_resolution(
                args['orthophoto_resolution'],
                opensfm_reconstruction,
                ignore_gsd=args['ignore_gsd'],
                ignore_resolution=not reconstruction.is_georeferenced(),
                has_gcp=reconstruction.has_gcp()) / 100.0

            dsm_multiplier = max(
                1.0,
                gsd.rounded_gsd(opensfm_reconstruction,
                                default_value=4,
                                ndigits=3,
                                ignore_gsd=args['ignore_gsd']))

            # A good DSM size depends on the flight altitude.
            # Flights at low altitude need more details (higher resolution)
            # Flights at higher altitude benefit from smoother surfaces (lower resolution)
            dsm_resolution = ortho_resolution * dsm_multiplier

            dsm_radius = dsm_resolution * math.sqrt(2)

            # Sparse point clouds benefits from using
            # a larger radius interolation --> less holes
            if args['fast_orthophoto']:
                dsm_radius *= 2

            log.ODM_INFO('ODM 2.5D DSM resolution: %s' % dsm_resolution)

            mesh.create_25dmesh(
                filter_point_cloud_path,
                odm_mesh_ply,
                dsm_radius=dsm_radius,
                dsm_resolution=dsm_resolution,
                depth=oct_tree,
                maxVertexCount=max_vertex,
                samples=samples,
                verbose=verbose,
                available_cores=max_concurrency,
                method='poisson' if args['fast_orthophoto'] else 'gridded',
                smooth_dsm=not args['fast_orthophoto'])
        else:
            log.ODM_WARNING('Found a valid ODM 2.5D Mesh file in: %s' %
                            odm_mesh_ply)
Exemple #4
0
    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
                    verbose=self.params.get('verbose'))

            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)
                ortho_resolution = gsd.cap_resolution(
                    args.orthophoto_resolution,
                    tree.opensfm_reconstruction,
                    ignore_gsd=args.ignore_gsd,
                    ignore_resolution=(not reconstruction.is_georeferenced())
                    and args.ignore_gsd,
                    has_gcp=reconstruction.has_gcp()) / 100.0

                dsm_multiplier = max(
                    1.0,
                    gsd.rounded_gsd(tree.opensfm_reconstruction,
                                    default_value=4,
                                    ndigits=3,
                                    ignore_gsd=args.ignore_gsd))

                # A good DSM size depends on the flight altitude.
                # Flights at low altitude need more details (higher resolution)
                # Flights at higher altitude benefit from smoother surfaces (lower resolution)
                dsm_resolution = ortho_resolution * dsm_multiplier

                dsm_radius = dsm_resolution * math.sqrt(2)

                if args.fast_orthophoto:
                    dsm_radius *= 2
                    dsm_resolution *= 8

                log.ODM_INFO('ODM 2.5D DSM resolution: %s' % dsm_resolution)

                mesh.create_25dmesh(
                    tree.filtered_point_cloud,
                    tree.odm_25dmesh,
                    dsm_radius=dsm_radius,
                    dsm_resolution=dsm_resolution,
                    depth=self.params.get('oct_tree'),
                    maxVertexCount=self.params.get('max_vertex'),
                    samples=self.params.get('samples'),
                    verbose=self.params.get('verbose'),
                    available_cores=args.max_concurrency,
                    method='poisson' if args.fast_orthophoto else 'gridded',
                    smooth_dsm=True)
            else:
                log.ODM_WARNING('Found a valid ODM 2.5D Mesh file in: %s' %
                                tree.odm_25dmesh)
Exemple #5
0
    def process(self, inputs, outputs):

        # Benchmarking
        start_time = system.now_raw()

        log.ODM_INFO('Running ODM Meshing Cell')

        # get inputs
        args = inputs.args
        tree = inputs.tree
        reconstruction = inputs.reconstruction

        # define paths and create working directories
        system.mkdir_p(tree.odm_meshing)

        # check if we rerun cell or not
        rerun_cell = (args.rerun is not None and
                      args.rerun == 'odm_meshing') or \
                     (args.rerun_all) or \
                     (args.rerun_from is not None and
                      'odm_meshing' in args.rerun_from)

        infile = tree.smvs_model
        if args.fast_orthophoto:
            infile = os.path.join(tree.opensfm, 'reconstruction.ply')
        elif args.use_opensfm_dense:
            infile = tree.opensfm_model

        # Create full 3D model unless --skip-3dmodel is set
        if not args.skip_3dmodel:
            if not io.file_exists(tree.odm_mesh) or rerun_cell:
                log.ODM_DEBUG('Writing ODM Mesh file in: %s' % tree.odm_mesh)

                mesh.screened_poisson_reconstruction(
                    infile,
                    tree.odm_mesh,
                    depth=self.params.oct_tree,
                    samples=self.params.samples,
                    maxVertexCount=self.params.max_vertex,
                    pointWeight=self.params.point_weight,
                    threads=self.params.max_concurrency,
                    verbose=self.params.verbose)

            else:
                log.ODM_WARNING('Found a valid ODM Mesh file in: %s' %
                                tree.odm_mesh)

        # 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 rerun_cell:

                log.ODM_DEBUG('Writing ODM 2.5D Mesh file in: %s' %
                              tree.odm_25dmesh)
                ortho_resolution = gsd.cap_resolution(
                    args.orthophoto_resolution,
                    tree.opensfm_reconstruction,
                    ignore_gsd=args.ignore_gsd) / 100.0

                dsm_multiplier = max(
                    1.0,
                    gsd.rounded_gsd(tree.opensfm_reconstruction,
                                    default_value=4,
                                    ndigits=3,
                                    ignore_gsd=args.ignore_gsd))

                # A good DSM size depends on the flight altitude.
                # Flights at low altitude need more details (higher resolution)
                # Flights at higher altitude benefit from smoother surfaces (lower resolution)
                dsm_resolution = ortho_resolution * dsm_multiplier

                dsm_radius = dsm_resolution * math.sqrt(2)

                # Sparse point clouds benefits from using
                # a larger radius interolation --> less holes
                if args.fast_orthophoto:
                    dsm_radius *= 2

                log.ODM_DEBUG('ODM 2.5D DSM resolution: %s' % dsm_resolution)

                mesh.create_25dmesh(
                    infile,
                    tree.odm_25dmesh,
                    dsm_radius=dsm_radius,
                    dsm_resolution=dsm_resolution,
                    depth=self.params.oct_tree,
                    maxVertexCount=self.params.max_vertex,
                    samples=self.params.samples,
                    verbose=self.params.verbose,
                    max_workers=args.max_concurrency,
                    method='poisson' if args.fast_orthophoto else 'gridded')
            else:
                log.ODM_WARNING('Found a valid ODM 2.5D Mesh file in: %s' %
                                tree.odm_25dmesh)

        outputs.reconstruction = reconstruction

        if args.time:
            system.benchmark(start_time, tree.benchmarking, 'Meshing')

        log.ODM_INFO('Running ODM Meshing Cell - Finished')
        return ecto.OK if args.end_with != 'odm_meshing' else ecto.QUIT