Skip to content

Commit

Permalink
save names
Browse files Browse the repository at this point in the history
Signed-off-by: YunLiu <[email protected]>
  • Loading branch information
KumoLiu committed Dec 11, 2024
1 parent 69a13d2 commit 25d1ce2
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 63 deletions.
85 changes: 37 additions & 48 deletions modules/omniverse/omniverse_integration.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,19 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"MONAI version: 1.4.0+19.gb1e915c3\n",
"MONAI version: 1.4.1rc1\n",
"Numpy version: 1.24.4\n",
"Pytorch version: 2.5.0a0+e000cf0ad9.nv24.10\n",
"MONAI flags: HAS_EXT = True, USE_COMPILED = False, USE_META_DICT = False\n",
"MONAI rev id: b1e915c323a8065cfe9e92de3013476f2f67c1b2\n",
"MONAI __file__: /opt/monai/monai/__init__.py\n",
"Pytorch version: 2.5.0a0+872d972e41.nv24.08\n",
"MONAI flags: HAS_EXT = False, USE_COMPILED = False, USE_META_DICT = False\n",
"MONAI rev id: e604d1841fe60c0ffb6978ae4116535ca8d8f34f\n",
"MONAI __file__: /workspace/Code/MONAI/monai/__init__.py\n",
"\n",
"Optional dependencies:\n",
"Pytorch Ignite version: 0.4.11\n",
Expand All @@ -105,7 +105,7 @@
"pandas version: 2.2.2\n",
"einops version: 0.8.0\n",
"transformers version: 4.40.2\n",
"mlflow version: 2.18.0\n",
"mlflow version: 2.17.2\n",
"pynrrd version: 1.1.1\n",
"clearml version: 1.16.5\n",
"\n",
Expand All @@ -122,7 +122,7 @@
"\n",
"import vtk\n",
"import vtkmodules\n",
"from ipyvtklink.viewer import ViewInteractiveWidget\n",
"# from ipyvtklink.viewer import ViewInteractiveWidget\n",
"\n",
"from utility import convert_to_mesh, convert_mesh_to_usd\n",
"\n",
Expand All @@ -146,7 +146,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 2,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -184,31 +184,18 @@
"name": "stdout",
"output_type": "stream",
"text": [
"2024-12-05 06:15:11,403 - INFO - --- input summary of monai.bundle.scripts.download ---\n",
"2024-12-05 06:15:11,403 - INFO - > name: 'maisi_ct_generative'\n",
"2024-12-05 06:15:11,404 - INFO - > bundle_dir: '/workspace/Data'\n",
"2024-12-05 06:15:11,404 - INFO - > source: 'monaihosting'\n",
"2024-12-05 06:15:11,404 - INFO - > remove_prefix: 'monai_'\n",
"2024-12-05 06:15:11,405 - INFO - > progress: True\n",
"2024-12-05 06:15:11,405 - INFO - ---\n",
"2024-12-11 11:31:31,904 - INFO - --- input summary of monai.bundle.scripts.download ---\n",
"2024-12-11 11:31:31,905 - INFO - > name: 'maisi_ct_generative'\n",
"2024-12-11 11:31:31,905 - INFO - > bundle_dir: '/workspace/Data'\n",
"2024-12-11 11:31:31,905 - INFO - > source: 'monaihosting'\n",
"2024-12-11 11:31:31,906 - INFO - > remove_prefix: 'monai_'\n",
"2024-12-11 11:31:31,906 - INFO - > progress: True\n",
"2024-12-11 11:31:31,906 - INFO - ---\n",
"\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"maisi_ct_generative_v0.4.5.zip: 13.0GB [09:25, 24.6MB/s] \n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"2024-12-05 06:25:02,608 - INFO - Downloaded: /workspace/Data/maisi_ct_generative_v0.4.5.zip\n",
"2024-12-05 06:25:02,615 - INFO - Expected md5 is None, skip md5 check for file /workspace/Data/maisi_ct_generative_v0.4.5.zip.\n",
"2024-12-05 06:25:02,616 - INFO - Writing into directory: /workspace/Data.\n"
"\n",
"2024-12-11 11:31:32,611 - INFO - Expected md5 is None, skip md5 check for file /workspace/Data/maisi_ct_generative_v0.4.5.zip.\n",
"2024-12-11 11:31:32,612 - INFO - File exists: /workspace/Data/maisi_ct_generative_v0.4.5.zip, skipped downloading.\n",
"2024-12-11 11:31:32,612 - INFO - Writing into directory: /workspace/Data.\n"
]
}
],
Expand All @@ -235,19 +222,19 @@
"name": "stdout",
"output_type": "stream",
"text": [
"2024-12-05 08:14:54,771 - INFO - Setting logging properties based on config: /workspace/Data/maisi_ct_generative/configs/logging.conf.\n",
"2024-12-05 08:14:54,772 - py.warnings - WARNING - Detected deprecated name 'optional_packages_version' in configuration file, replacing with 'required_packages_version'.\n",
"2024-12-11 11:32:14,010 - INFO - Setting logging properties based on config: /workspace/Data/maisi_ct_generative/configs/logging.conf.\n",
"2024-12-11 11:32:14,011 - py.warnings - WARNING - Detected deprecated name 'optional_packages_version' in configuration file, replacing with 'required_packages_version'.\n",
"\n",
"2024-12-05 08:14:54,783 - INFO - --- input summary of monai.bundle.scripts.run ---\n",
"2024-12-05 08:14:54,784 - INFO - > workflow_type: 'inference'\n",
"2024-12-05 08:14:54,784 - INFO - > bundle_root: '/workspace/Data/maisi_ct_generative'\n",
"2024-12-05 08:14:54,784 - INFO - > output_size_xy: 256\n",
"2024-12-05 08:14:54,784 - INFO - > output_size_z: 256\n",
"2024-12-05 08:14:54,785 - INFO - > spacing_xy: 1.5\n",
"2024-12-05 08:14:54,785 - INFO - > spacing_z: 1.5\n",
"2024-12-05 08:14:54,785 - INFO - > autoencoder_def#num_splits: 16\n",
"2024-12-05 08:14:54,785 - INFO - > mask_generation_autoencoder_def#num_splits: 16\n",
"2024-12-05 08:14:54,786 - INFO - ---\n",
"2024-12-11 11:32:14,021 - INFO - --- input summary of monai.bundle.scripts.run ---\n",
"2024-12-11 11:32:14,022 - INFO - > workflow_type: 'inference'\n",
"2024-12-11 11:32:14,022 - INFO - > bundle_root: '/workspace/Data/maisi_ct_generative'\n",
"2024-12-11 11:32:14,022 - INFO - > output_size_xy: 256\n",
"2024-12-11 11:32:14,022 - INFO - > output_size_z: 256\n",
"2024-12-11 11:32:14,022 - INFO - > spacing_xy: 1.5\n",
"2024-12-11 11:32:14,023 - INFO - > spacing_z: 1.5\n",
"2024-12-11 11:32:14,023 - INFO - > autoencoder_def#num_splits: 16\n",
"2024-12-11 11:32:14,023 - INFO - > mask_generation_autoencoder_def#num_splits: 16\n",
"2024-12-11 11:32:14,023 - INFO - ---\n",
"\n",
"\n"
]
Expand Down Expand Up @@ -440,6 +427,7 @@
" )\n",
" orig_seg = pre_trans({\"label\": input_nii_path})[\"label\"]\n",
" all_organ = np.zeros_like(orig_seg, dtype=np.uint8)\n",
" all_label_values = {}\n",
"\n",
" save_trans = SaveImage(output_ext=\"nii.gz\", output_dtype=np.uint8)\n",
" for j, (organ_name, label_val) in enumerate(labels.items(), start=1):\n",
Expand All @@ -462,14 +450,15 @@
" smoothing_factor=0.5,\n",
" reduction_ratio=0.0,\n",
" )\n",
" all_label_values[j] = organ_name\n",
"\n",
" all_organ_filename = os.path.join(output_nii_path, \"all_organs\")\n",
" save_trans(all_organ[None], meta_data=orig_seg.meta, filename=all_organ_filename)\n",
" convert_to_mesh(\n",
" f\"{all_organ_filename}.nii.gz\",\n",
" output_obj_path,\n",
" \"all_organs.gltf\",\n",
" label_value=list(range(1, 18)),\n",
" label_value=all_label_values,\n",
" smoothing_factor=0.6,\n",
" reduction_ratio=0.0,\n",
" )\n",
Expand Down Expand Up @@ -593,7 +582,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "base",
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
Expand All @@ -607,7 +596,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.20"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
45 changes: 30 additions & 15 deletions modules/omniverse/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ def convert_to_mesh(
reader.SetFileName(segmentation_path)
reader.Update()

label_values = [label_value] if isinstance(label_value, int) else label_value
if len(label_values) > 1:
label_values = {label_value: None} if isinstance(label_value, int) else label_value
if len(label_values.keys()) > 1:
renderer = vtk.vtkRenderer()
render_window = vtk.vtkRenderWindow()
render_window.AddRenderer(renderer)
for i in label_values:
actor_metadata = {}
for i, name in label_values.items():
# Step 2: Create Closed Surface Representation using vtkDiscreteFlyingEdges3D
flying_edges = vtk.vtkDiscreteFlyingEdges3D()
flying_edges.SetInputConnection(reader.GetOutputPort())
Expand Down Expand Up @@ -82,28 +83,21 @@ def convert_to_mesh(
smoothing_filter.NormalizeCoordinatesOn()
smoothing_filter.Update()

# Step 5: Generate normals for better shading
# normals_filter = vtk.vtkPolyDataNormals()
# normals_filter.SetInputConnection(smoothing_filter.GetOutputPort())
# normals_filter.SplittingOff()
# normals_filter.ConsistencyOn()
# normals_filter.Update()

# Step 6: Decimate the mesh further
# Step 5: Decimate the mesh further
decimation = vtk.vtkQuadricDecimation()
decimation.SetInputConnection(smoothing_filter.GetOutputPort())
decimation.SetTargetReduction(0.9) # 90% reduction, the same as slicer
decimation.VolumePreservationOn()
decimation.Update()

# Step 7: Generate normals for better shading
# Step 6: Generate normals for better shading
decimatedNormals = vtk.vtkPolyDataNormals()
decimatedNormals.SetInputConnection(decimation.GetOutputPort())
decimatedNormals.SplittingOff()
decimatedNormals.ConsistencyOn()
decimatedNormals.Update()

# Step 8: convert to LPS
# Step 7: convert to LPS
ras2lps = vtk.vtkMatrix4x4()
ras2lps.SetElement(0, 0, -1)
ras2lps.SetElement(1, 1, -1)
Expand All @@ -114,7 +108,7 @@ def convert_to_mesh(
transformer.SetInputConnection(decimatedNormals.GetOutputPort())
transformer.Update()

if len(label_values) > 1:
if len(label_values.keys()) > 1:
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(transformer.GetOutput())
actor = vtk.vtkActor()
Expand All @@ -128,10 +122,11 @@ def convert_to_mesh(
vtk.vtkMath.HSVToRGB(colorHSV, colorRGB)
actor.GetProperty().SetColor(colorRGB[0], colorRGB[1], colorRGB[2])
actor.GetProperty().SetInterpolationToGouraud()
actor_metadata[actor] = name
renderer.AddActor(actor)

output_filename = os.path.join(output_folder, filename)
if len(label_values) > 1:
if len(label_values.keys()) > 1:
exporter = vtk.vtkGLTFExporter()
exporter.SetFileName(output_filename)
exporter.SetRenderWindow(render_window)
Expand All @@ -146,6 +141,26 @@ def convert_to_mesh(
writer.Write()

print(f"Mesh successfully exported to {output_filename}")

if len(label_values.keys()) > 1:
# Modify GLTF to include actor names
with open(output_filename, "r") as f:
gltf_data = json.load(f)

# Iterate over actors and add names to GLTF nodes
actors = renderer.GetActors()
actors.InitTraversal()

for i, node in enumerate(gltf_data.get("nodes", [])):
actor = actors.GetNextActor()
if actor in actor_metadata:
node["name"] = actor_metadata[actor]

# Save the modified GLTF file
modified_output_filename = output_filename.replace(".gltf", "_modified.gltf")
with open(modified_output_filename, "w") as f:
json.dump(gltf_data, f, indent=2)
print(f"Modified GLTF successfully exported to {modified_output_filename}")


def convert_mesh_to_usd(input_file, output_file):
Expand Down

0 comments on commit 25d1ce2

Please sign in to comment.