Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ply #1829

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft

Fix ply #1829

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions contrib/fix_ply/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# fix_ply.py

Use to translate a modified ply into a compatible format for subsequent steps in ODM. Via Jaime Chacoff, https://community.opendronemap.org/t/edited-point-cloud-with-cloudcompare-wont-rerun-from-odm-meshing/21449/6
60 changes: 60 additions & 0 deletions contrib/fix_ply/fix_ply.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import os
from plyfile import PlyData, PlyElement, PlyProperty
import open3d as o3d
import numpy as np


def pcd_ascii_to_binary_ply(_ply_file: str, _binary_ply: str) -> None:
""" Converts a .ply saved as ASCII format to a .ply saved with binary format and properties compatible with ODM"""

ply_data: PlyData = PlyData.read(_ply_file)

new_elements: list[PlyElement] = []

for element in ply_data.elements:
if 'scalar_views' in element.data.dtype.names:
new_dtype: list[tuple[str, str]] = []
for name in element.data.dtype.names:
if name == 'scalar_views':
new_dtype.append(('views', 'u1'))
else:
new_dtype.append((name, element.data.dtype[name]))

new_data = np.empty(element.data.shape, dtype=new_dtype)

for name in element.data.dtype.names:
if name == 'scalar_views':
new_data['views'] = element.data[name].astype('u1')
else:
new_data[name] = element.data[name]

new_element = PlyElement.describe(new_data, element.name)
else:
new_element = PlyElement.describe(element.data, element.name)

new_elements.append(new_element)

new_ply_data = PlyData(new_elements, text=False)

with open(_binary_ply, 'wb') as f:
new_ply_data.write(f)


def view_point_cloud(_input_ply: str) -> None:
pcd = o3d.io.read_point_cloud(_input_ply)
o3d.visualization.draw_geometries([pcd])


if __name__ == '__main__':

# Parameters
base: str = os.path.join('D:\\', '01_droneo', 'DJI_202407311545_024', 'odm_filterpoints')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are pretty specific hard-coded paths; should this program be modified to be a bit more generic before merging?

Copy link
Contributor Author

@smathermather smathermather Feb 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure. I was hoping to get permission from Jaime before proceeding with edits (originally posted here). Otherwise, I'll just re-write from the ground up using a similar approach.

ply_file: str = os.path.join(base, 'point_cloud_ascii.ply')
binary_ply_file: str = os.path.join(base, 'point_cloud.ply')

if not os.path.isfile(ply_file):
raise "File doesn't exist"

pcd_ascii_to_binary_ply(ply_file, binary_ply_file)

view_point_cloud(binary_ply_file)
Loading