diff --git a/SuperBuild/cmake/External-Untwine.cmake b/SuperBuild/cmake/External-Untwine.cmake index e72238fc..543df868 100644 --- a/SuperBuild/cmake/External-Untwine.cmake +++ b/SuperBuild/cmake/External-Untwine.cmake @@ -9,7 +9,7 @@ ExternalProject_Add(${_proj_name} #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} GIT_REPOSITORY https://github.com/hobu/untwine/ - GIT_TAG 20243113fc7e9a3056f4ec727cc1f69202669156 + GIT_TAG 69c240a7225180f7d8c5bc0eee500ffaf987f81a #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- diff --git a/VERSION b/VERSION index dbe59006..1817afea 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.8.1 +2.8.2 diff --git a/opendm/config.py b/opendm/config.py index a0d683e2..ce9f4be4 100755 --- a/opendm/config.py +++ b/opendm/config.py @@ -360,6 +360,12 @@ def config(argv=None, parser=None): default=False, help='Export the georeferenced point cloud in Entwine Point Tile (EPT) format. Default: %(default)s') + parser.add_argument('--pc-copc', + action=StoreTrue, + nargs=0, + default=False, + help='Save the georeferenced point cloud in Cloud Optimized Point Cloud (COPC) format. Default: %(default)s') + parser.add_argument('--pc-filter', metavar='', action=StoreValue, diff --git a/opendm/entwine.py b/opendm/entwine.py index 04ec3b4d..265e4fd9 100644 --- a/opendm/entwine.py +++ b/opendm/entwine.py @@ -39,7 +39,7 @@ def build(input_point_cloud_files, output_path, max_concurrency=8, rerun=False): log.ODM_WARNING("Cannot build EPT using entwine (%s), attempting with untwine..." % str(e)) dir_cleanup() build_untwine(input_point_cloud_files, tmpdir, output_path, max_concurrency=max_concurrency) - + if os.path.exists(tmpdir): shutil.rmtree(tmpdir) @@ -67,3 +67,26 @@ def build_untwine(input_point_cloud_files, tmpdir, output_path, max_concurrency= # Run untwine system.run('untwine --temp_dir "{tmpdir}" {files} --output_dir "{outputdir}"'.format(**kwargs)) + +def build_copc(input_point_cloud_files, output_file): + if len(input_point_cloud_files) == 0: + logger.ODM_WARNING("Cannot build COPC, no input files") + return + + base_path, ext = os.path.splitext(output_file) + tmpdir = io.related_file_path(base_path, postfix="-tmp") + if os.path.exists(tmpdir): + log.ODM_WARNING("Removing previous directory %s" % tmpdir) + shutil.rmtree(tmpdir) + + kwargs = { + 'tmpdir': tmpdir, + 'files': "--files " + " ".join(map(double_quote, input_point_cloud_files)), + 'output': output_file + } + + # Run untwine + system.run('untwine --temp_dir "{tmpdir}" {files} -o "{output}" --single_file'.format(**kwargs)) + + if os.path.exists(tmpdir): + shutil.rmtree(tmpdir) \ No newline at end of file diff --git a/opendm/point_cloud.py b/opendm/point_cloud.py index e29f5474..92f47c7a 100644 --- a/opendm/point_cloud.py +++ b/opendm/point_cloud.py @@ -285,3 +285,14 @@ def post_point_cloud_steps(args, tree, rerun=False): if args.pc_ept: log.ODM_INFO("Creating Entwine Point Tile output") entwine.build([tree.odm_georeferencing_model_laz], tree.entwine_pointcloud, max_concurrency=args.max_concurrency, rerun=rerun) + + # COPC point clouds + if args.pc_copc: + log.ODM_INFO("Creating Cloud Optimized Point Cloud (COPC)") + + copc_output = io.related_file_path(tree.odm_georeferencing_model_laz, postfix="-copc") + entwine.build_copc([tree.odm_georeferencing_model_laz], copc_output) + if os.path.exists(copc_output): + # Swap + os.remove(tree.odm_georeferencing_model_laz) + shutil.move(copc_output, tree.odm_georeferencing_model_laz) \ No newline at end of file