Skip to content

Commit ac1bbcf

Browse files
committed
Make texture files optional for loading and writing photoscans (#412)
1 parent a204903 commit ac1bbcf

2 files changed

Lines changed: 15 additions & 12 deletions

File tree

src/openlifu/db/database.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -474,9 +474,9 @@ def write_photocollection(self, subject_id, session_id, reference_number: str, p
474474
self.logger.info(f"Added photocollection with reference number {reference_number} for session {session_id} to the database.")
475475

476476
def write_photoscan(self, subject_id, session_id, photoscan: Photoscan, model_data_filepath: str | None = None, texture_data_filepath: str | None = None, mtl_data_filepath: str | None = None, on_conflict=OnConflictOpts.ERROR):
477-
""" Writes a photoscan object to database and copies the associated model and texture data filepaths that are required for generating a photoscan into the database.
478-
.mtl files are not required for generating a photoscan but can be provided if present.
479-
When a photoscan that is already present in the database is being re-written,the associated model and texture files do not need to be provided """
477+
""" Writes a photoscan object to database and copies the associated data filepaths into the database.
478+
While the model data file is required, the associated texture and .mtl files are optional and can be provided if present.
479+
When a photoscan that is already present in the database is being re-written,the associated data files do not need to be specified """
480480

481481
photoscan_ids = self.get_photoscan_ids(subject_id, session_id)
482482
if photoscan.id in photoscan_ids:
@@ -512,7 +512,7 @@ def write_photoscan(self, subject_id, session_id, photoscan: Photoscan, model_da
512512
raise FileNotFoundError(f'Texture data filepath does not exist: {texture_data_filepath}')
513513
photoscan.texture_filename = texture_data_filepath.name
514514
shutil.copy(texture_data_filepath, photoscan_metadata_filepath.parent)
515-
elif not photoscan.texture_filename or not (photoscan_parent_dir/photoscan.texture_filename).exists():
515+
elif photoscan.texture_filename and not (photoscan_parent_dir/photoscan.texture_filename).exists():
516516
raise ValueError(f"Cannot find texture file associated with photoscan {photoscan.id}.")
517517

518518
# Not necessarily required for a photoscan object
@@ -522,9 +522,8 @@ def write_photoscan(self, subject_id, session_id, photoscan: Photoscan, model_da
522522
raise FileNotFoundError(f'MTL filepath does not exist: {mtl_data_filepath}')
523523
photoscan.mtl_filename = mtl_data_filepath.name
524524
shutil.copy(mtl_data_filepath, photoscan_metadata_filepath.parent)
525-
elif photoscan.mtl_filename:
526-
if not (photoscan_parent_dir/photoscan.mtl_filename).exists():
527-
raise ValueError(f"Cannot find photoscan materials file associated with photoscan {photoscan.id}.")
525+
elif photoscan.mtl_filename and not (photoscan_parent_dir/photoscan.mtl_filename).exists():
526+
raise ValueError(f"Cannot find photoscan materials file associated with photoscan {photoscan.id}.")
528527

529528
#Save the photoscan metadata to a JSON file
530529
photoscan.to_file(photoscan_metadata_filepath)
@@ -814,7 +813,7 @@ def get_photoscan_absolute_filepaths_info(self, subject_id, session_id, photosca
814813

815814
def load_photoscan(self, subject_id, session_id, photoscan_id, load_data = False):
816815
"""Returns a photoscan object and optionally, also returns the loaded model and texture
817-
data as Tuple[vtkPolyData, vtkImageData] if load_data = True."""
816+
data as Tuple[vtkPolyData, vtkImageData | None ] if load_data = True."""
818817

819818
photoscan_metadata_filepath = self.get_photoscan_metadata_filepath(subject_id, session_id, photoscan_id)
820819
if not photoscan_metadata_filepath.exists() or not photoscan_metadata_filepath.is_file():

src/openlifu/nav/photoscan.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,25 +105,29 @@ def to_file(self, filename):
105105
with open(filename, 'w') as file:
106106
file.write(self.to_json(compact = False))
107107

108-
def load_data_from_filepaths(model_abspath: str, texture_abspath: str) -> Tuple[vtk.vtkPolyData, vtk.vtkImageData]:
108+
def load_data_from_filepaths(model_abspath: str, texture_abspath: str | None) -> Tuple[vtk.vtkPolyData, vtk.vtkImageData | None]:
109109
"""
110110
This function returns the data directly from the model and texture filepaths without requiring a photoscan object.
111111
param model_abspath: absolute filepath to model data
112112
texture abspath: absolute filepath to texture data
113113
Returns: Photoscan data as (model_vtkpolydata, texture_vtkimagedata)
114114
"""
115115
model_polydata = load_model(model_abspath)
116-
texture_imagedata = load_texture(texture_abspath)
116+
texture_imagedata = None
117+
if texture_abspath:
118+
texture_imagedata = load_texture(texture_abspath)
117119

118120
return (model_polydata, texture_imagedata)
119121

120-
def load_data_from_photoscan(photoscan: Photoscan, parent_dir) -> Tuple[vtk.vtkPolyData, vtk.vtkImageData]:
122+
def load_data_from_photoscan(photoscan: Photoscan, parent_dir) -> Tuple[vtk.vtkPolyData, vtk.vtkImageData | None]:
121123
"""
122124
param parent_dir: parent directory containing model and texture data filepaths
123125
Returns: Photoscan data as (model_vtkpolydata, texture_vtkimagedata)
124126
"""
125127
model_polydata = load_model(Path(parent_dir)/photoscan.model_filename)
126-
texture_imagedata = load_texture(Path(parent_dir)/photoscan.texture_filename)
128+
texture_imagedata = None
129+
if photoscan.texture_filename:
130+
texture_imagedata = load_texture(Path(parent_dir)/photoscan.texture_filename)
127131

128132
return (model_polydata, texture_imagedata)
129133

0 commit comments

Comments
 (0)