Skip to content

Commit 25d1ce2

Browse files
committed
save names
Signed-off-by: YunLiu <[email protected]>
1 parent 69a13d2 commit 25d1ce2

File tree

2 files changed

+67
-63
lines changed

2 files changed

+67
-63
lines changed

modules/omniverse/omniverse_integration.ipynb

Lines changed: 37 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,19 @@
7575
},
7676
{
7777
"cell_type": "code",
78-
"execution_count": 2,
78+
"execution_count": 1,
7979
"metadata": {},
8080
"outputs": [
8181
{
8282
"name": "stdout",
8383
"output_type": "stream",
8484
"text": [
85-
"MONAI version: 1.4.0+19.gb1e915c3\n",
85+
"MONAI version: 1.4.1rc1\n",
8686
"Numpy version: 1.24.4\n",
87-
"Pytorch version: 2.5.0a0+e000cf0ad9.nv24.10\n",
88-
"MONAI flags: HAS_EXT = True, USE_COMPILED = False, USE_META_DICT = False\n",
89-
"MONAI rev id: b1e915c323a8065cfe9e92de3013476f2f67c1b2\n",
90-
"MONAI __file__: /opt/monai/monai/__init__.py\n",
87+
"Pytorch version: 2.5.0a0+872d972e41.nv24.08\n",
88+
"MONAI flags: HAS_EXT = False, USE_COMPILED = False, USE_META_DICT = False\n",
89+
"MONAI rev id: e604d1841fe60c0ffb6978ae4116535ca8d8f34f\n",
90+
"MONAI __file__: /workspace/Code/MONAI/monai/__init__.py\n",
9191
"\n",
9292
"Optional dependencies:\n",
9393
"Pytorch Ignite version: 0.4.11\n",
@@ -105,7 +105,7 @@
105105
"pandas version: 2.2.2\n",
106106
"einops version: 0.8.0\n",
107107
"transformers version: 4.40.2\n",
108-
"mlflow version: 2.18.0\n",
108+
"mlflow version: 2.17.2\n",
109109
"pynrrd version: 1.1.1\n",
110110
"clearml version: 1.16.5\n",
111111
"\n",
@@ -122,7 +122,7 @@
122122
"\n",
123123
"import vtk\n",
124124
"import vtkmodules\n",
125-
"from ipyvtklink.viewer import ViewInteractiveWidget\n",
125+
"# from ipyvtklink.viewer import ViewInteractiveWidget\n",
126126
"\n",
127127
"from utility import convert_to_mesh, convert_mesh_to_usd\n",
128128
"\n",
@@ -146,7 +146,7 @@
146146
},
147147
{
148148
"cell_type": "code",
149-
"execution_count": 3,
149+
"execution_count": 2,
150150
"metadata": {},
151151
"outputs": [
152152
{
@@ -184,31 +184,18 @@
184184
"name": "stdout",
185185
"output_type": "stream",
186186
"text": [
187-
"2024-12-05 06:15:11,403 - INFO - --- input summary of monai.bundle.scripts.download ---\n",
188-
"2024-12-05 06:15:11,403 - INFO - > name: 'maisi_ct_generative'\n",
189-
"2024-12-05 06:15:11,404 - INFO - > bundle_dir: '/workspace/Data'\n",
190-
"2024-12-05 06:15:11,404 - INFO - > source: 'monaihosting'\n",
191-
"2024-12-05 06:15:11,404 - INFO - > remove_prefix: 'monai_'\n",
192-
"2024-12-05 06:15:11,405 - INFO - > progress: True\n",
193-
"2024-12-05 06:15:11,405 - INFO - ---\n",
187+
"2024-12-11 11:31:31,904 - INFO - --- input summary of monai.bundle.scripts.download ---\n",
188+
"2024-12-11 11:31:31,905 - INFO - > name: 'maisi_ct_generative'\n",
189+
"2024-12-11 11:31:31,905 - INFO - > bundle_dir: '/workspace/Data'\n",
190+
"2024-12-11 11:31:31,905 - INFO - > source: 'monaihosting'\n",
191+
"2024-12-11 11:31:31,906 - INFO - > remove_prefix: 'monai_'\n",
192+
"2024-12-11 11:31:31,906 - INFO - > progress: True\n",
193+
"2024-12-11 11:31:31,906 - INFO - ---\n",
194194
"\n",
195-
"\n"
196-
]
197-
},
198-
{
199-
"name": "stderr",
200-
"output_type": "stream",
201-
"text": [
202-
"maisi_ct_generative_v0.4.5.zip: 13.0GB [09:25, 24.6MB/s] \n"
203-
]
204-
},
205-
{
206-
"name": "stdout",
207-
"output_type": "stream",
208-
"text": [
209-
"2024-12-05 06:25:02,608 - INFO - Downloaded: /workspace/Data/maisi_ct_generative_v0.4.5.zip\n",
210-
"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",
211-
"2024-12-05 06:25:02,616 - INFO - Writing into directory: /workspace/Data.\n"
195+
"\n",
196+
"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",
197+
"2024-12-11 11:31:32,612 - INFO - File exists: /workspace/Data/maisi_ct_generative_v0.4.5.zip, skipped downloading.\n",
198+
"2024-12-11 11:31:32,612 - INFO - Writing into directory: /workspace/Data.\n"
212199
]
213200
}
214201
],
@@ -235,19 +222,19 @@
235222
"name": "stdout",
236223
"output_type": "stream",
237224
"text": [
238-
"2024-12-05 08:14:54,771 - INFO - Setting logging properties based on config: /workspace/Data/maisi_ct_generative/configs/logging.conf.\n",
239-
"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",
225+
"2024-12-11 11:32:14,010 - INFO - Setting logging properties based on config: /workspace/Data/maisi_ct_generative/configs/logging.conf.\n",
226+
"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",
240227
"\n",
241-
"2024-12-05 08:14:54,783 - INFO - --- input summary of monai.bundle.scripts.run ---\n",
242-
"2024-12-05 08:14:54,784 - INFO - > workflow_type: 'inference'\n",
243-
"2024-12-05 08:14:54,784 - INFO - > bundle_root: '/workspace/Data/maisi_ct_generative'\n",
244-
"2024-12-05 08:14:54,784 - INFO - > output_size_xy: 256\n",
245-
"2024-12-05 08:14:54,784 - INFO - > output_size_z: 256\n",
246-
"2024-12-05 08:14:54,785 - INFO - > spacing_xy: 1.5\n",
247-
"2024-12-05 08:14:54,785 - INFO - > spacing_z: 1.5\n",
248-
"2024-12-05 08:14:54,785 - INFO - > autoencoder_def#num_splits: 16\n",
249-
"2024-12-05 08:14:54,785 - INFO - > mask_generation_autoencoder_def#num_splits: 16\n",
250-
"2024-12-05 08:14:54,786 - INFO - ---\n",
228+
"2024-12-11 11:32:14,021 - INFO - --- input summary of monai.bundle.scripts.run ---\n",
229+
"2024-12-11 11:32:14,022 - INFO - > workflow_type: 'inference'\n",
230+
"2024-12-11 11:32:14,022 - INFO - > bundle_root: '/workspace/Data/maisi_ct_generative'\n",
231+
"2024-12-11 11:32:14,022 - INFO - > output_size_xy: 256\n",
232+
"2024-12-11 11:32:14,022 - INFO - > output_size_z: 256\n",
233+
"2024-12-11 11:32:14,022 - INFO - > spacing_xy: 1.5\n",
234+
"2024-12-11 11:32:14,023 - INFO - > spacing_z: 1.5\n",
235+
"2024-12-11 11:32:14,023 - INFO - > autoencoder_def#num_splits: 16\n",
236+
"2024-12-11 11:32:14,023 - INFO - > mask_generation_autoencoder_def#num_splits: 16\n",
237+
"2024-12-11 11:32:14,023 - INFO - ---\n",
251238
"\n",
252239
"\n"
253240
]
@@ -440,6 +427,7 @@
440427
" )\n",
441428
" orig_seg = pre_trans({\"label\": input_nii_path})[\"label\"]\n",
442429
" all_organ = np.zeros_like(orig_seg, dtype=np.uint8)\n",
430+
" all_label_values = {}\n",
443431
"\n",
444432
" save_trans = SaveImage(output_ext=\"nii.gz\", output_dtype=np.uint8)\n",
445433
" for j, (organ_name, label_val) in enumerate(labels.items(), start=1):\n",
@@ -462,14 +450,15 @@
462450
" smoothing_factor=0.5,\n",
463451
" reduction_ratio=0.0,\n",
464452
" )\n",
453+
" all_label_values[j] = organ_name\n",
465454
"\n",
466455
" all_organ_filename = os.path.join(output_nii_path, \"all_organs\")\n",
467456
" save_trans(all_organ[None], meta_data=orig_seg.meta, filename=all_organ_filename)\n",
468457
" convert_to_mesh(\n",
469458
" f\"{all_organ_filename}.nii.gz\",\n",
470459
" output_obj_path,\n",
471460
" \"all_organs.gltf\",\n",
472-
" label_value=list(range(1, 18)),\n",
461+
" label_value=all_label_values,\n",
473462
" smoothing_factor=0.6,\n",
474463
" reduction_ratio=0.0,\n",
475464
" )\n",
@@ -593,7 +582,7 @@
593582
],
594583
"metadata": {
595584
"kernelspec": {
596-
"display_name": "base",
585+
"display_name": "Python 3",
597586
"language": "python",
598587
"name": "python3"
599588
},
@@ -607,7 +596,7 @@
607596
"name": "python",
608597
"nbconvert_exporter": "python",
609598
"pygments_lexer": "ipython3",
610-
"version": "3.9.20"
599+
"version": "3.10.12"
611600
}
612601
},
613602
"nbformat": 4,

modules/omniverse/utility.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,13 @@ def convert_to_mesh(
3737
reader.SetFileName(segmentation_path)
3838
reader.Update()
3939

40-
label_values = [label_value] if isinstance(label_value, int) else label_value
41-
if len(label_values) > 1:
40+
label_values = {label_value: None} if isinstance(label_value, int) else label_value
41+
if len(label_values.keys()) > 1:
4242
renderer = vtk.vtkRenderer()
4343
render_window = vtk.vtkRenderWindow()
4444
render_window.AddRenderer(renderer)
45-
for i in label_values:
45+
actor_metadata = {}
46+
for i, name in label_values.items():
4647
# Step 2: Create Closed Surface Representation using vtkDiscreteFlyingEdges3D
4748
flying_edges = vtk.vtkDiscreteFlyingEdges3D()
4849
flying_edges.SetInputConnection(reader.GetOutputPort())
@@ -82,28 +83,21 @@ def convert_to_mesh(
8283
smoothing_filter.NormalizeCoordinatesOn()
8384
smoothing_filter.Update()
8485

85-
# Step 5: Generate normals for better shading
86-
# normals_filter = vtk.vtkPolyDataNormals()
87-
# normals_filter.SetInputConnection(smoothing_filter.GetOutputPort())
88-
# normals_filter.SplittingOff()
89-
# normals_filter.ConsistencyOn()
90-
# normals_filter.Update()
91-
92-
# Step 6: Decimate the mesh further
86+
# Step 5: Decimate the mesh further
9387
decimation = vtk.vtkQuadricDecimation()
9488
decimation.SetInputConnection(smoothing_filter.GetOutputPort())
9589
decimation.SetTargetReduction(0.9) # 90% reduction, the same as slicer
9690
decimation.VolumePreservationOn()
9791
decimation.Update()
9892

99-
# Step 7: Generate normals for better shading
93+
# Step 6: Generate normals for better shading
10094
decimatedNormals = vtk.vtkPolyDataNormals()
10195
decimatedNormals.SetInputConnection(decimation.GetOutputPort())
10296
decimatedNormals.SplittingOff()
10397
decimatedNormals.ConsistencyOn()
10498
decimatedNormals.Update()
10599

106-
# Step 8: convert to LPS
100+
# Step 7: convert to LPS
107101
ras2lps = vtk.vtkMatrix4x4()
108102
ras2lps.SetElement(0, 0, -1)
109103
ras2lps.SetElement(1, 1, -1)
@@ -114,7 +108,7 @@ def convert_to_mesh(
114108
transformer.SetInputConnection(decimatedNormals.GetOutputPort())
115109
transformer.Update()
116110

117-
if len(label_values) > 1:
111+
if len(label_values.keys()) > 1:
118112
mapper = vtk.vtkPolyDataMapper()
119113
mapper.SetInputData(transformer.GetOutput())
120114
actor = vtk.vtkActor()
@@ -128,10 +122,11 @@ def convert_to_mesh(
128122
vtk.vtkMath.HSVToRGB(colorHSV, colorRGB)
129123
actor.GetProperty().SetColor(colorRGB[0], colorRGB[1], colorRGB[2])
130124
actor.GetProperty().SetInterpolationToGouraud()
125+
actor_metadata[actor] = name
131126
renderer.AddActor(actor)
132127

133128
output_filename = os.path.join(output_folder, filename)
134-
if len(label_values) > 1:
129+
if len(label_values.keys()) > 1:
135130
exporter = vtk.vtkGLTFExporter()
136131
exporter.SetFileName(output_filename)
137132
exporter.SetRenderWindow(render_window)
@@ -146,6 +141,26 @@ def convert_to_mesh(
146141
writer.Write()
147142

148143
print(f"Mesh successfully exported to {output_filename}")
144+
145+
if len(label_values.keys()) > 1:
146+
# Modify GLTF to include actor names
147+
with open(output_filename, "r") as f:
148+
gltf_data = json.load(f)
149+
150+
# Iterate over actors and add names to GLTF nodes
151+
actors = renderer.GetActors()
152+
actors.InitTraversal()
153+
154+
for i, node in enumerate(gltf_data.get("nodes", [])):
155+
actor = actors.GetNextActor()
156+
if actor in actor_metadata:
157+
node["name"] = actor_metadata[actor]
158+
159+
# Save the modified GLTF file
160+
modified_output_filename = output_filename.replace(".gltf", "_modified.gltf")
161+
with open(modified_output_filename, "w") as f:
162+
json.dump(gltf_data, f, indent=2)
163+
print(f"Modified GLTF successfully exported to {modified_output_filename}")
149164

150165

151166
def convert_mesh_to_usd(input_file, output_file):

0 commit comments

Comments
 (0)