11"""Export 3D objects."""
22
33from pathlib import Path
4- from typing import List
4+ from typing import List , Union
55
66import numpy as np
77import trimesh
@@ -24,47 +24,13 @@ def export3DObjects(series: Series, obj_names : list, output_dir : str, export_t
2424 void
2525 """
2626
27+ ## Collect 3D objects
28+
2729 obj_data = {}
2830
2931 for obj_name in obj_names :
3032
31- mode = series .getAttr (obj_name , "3D_mode" )
32-
33- if mode == "surface" :
34- obj_data [obj_name ] = Surface (obj_name , series )
35-
36- elif mode == "spheres" :
37- obj_data [obj_name ] = Spheres (obj_name , series )
38-
39- elif mode == "contours" :
40- obj_data [obj_name ] = Contours (obj_name , series )
41-
42- for snum , section in series .enumerateSections (show_progress = False ):
43-
44- # # Assume somewhat uniform section thickness
45- # tform = section.tform
46-
47- for obj_name in obj_names :
48-
49- if obj_name not in section .contours :
50-
51- continue
52-
53- ## Get objects alignment
54- obj_alignment = series .getAttr (obj_name , "alignment" )
55-
56- if not obj_alignment :
57-
58- tform = section .tform
59-
60- else :
61-
62- tform = section .tforms [obj_alignment ]
63-
64- for trace in section .contours [obj_name ]:
65-
66- ## Collect all points if generating full surface
67- obj_data [obj_name ].addTrace (trace , snum , tform )
33+ obj_data [obj_name ] = get_3D_mesh (series , obj_name )
6834
6935 ## Iterate through objects and export 3D meshes
7036
@@ -83,7 +49,93 @@ def export3DObjects(series: Series, obj_names : list, output_dir : str, export_t
8349
8450 if notify_user :
8551
86- notify (f"Object(s) exported to directory:\n \n { output_directory .absolute ()} \n " )
52+ notify (f"Object(s) exported to directory:\n \n { Path (output_directory ).absolute ()} \n " )
53+
54+
55+ def export3DData (series : Series , obj_names : list , output_fp : str , notify_user : bool = True ) -> None :
56+ """Export quantitative data from meshes."""
57+
58+ sep = ","
59+ csv_str = f"Series{ sep } Name{ sep } MeshType{ sep } SurfaceArea{ sep } Volume\n "
60+ series_code = series .code
61+
62+ errors = {}
63+
64+ for obj in obj_names :
65+
66+ try :
67+
68+ obj_data = get_3D_mesh (series , obj )
69+ obj_type = type (obj_data ).__name__ .lower ()
70+ tm = obj_data .generateTrimesh ()
71+
72+ surface_area = round (tm .area , 5 )
73+ volume = round (tm .volume , 5 )
74+
75+ csv_str += f"{ series_code } { sep } { obj } { sep } { obj_type } { sep } { surface_area } { sep } { volume } \n "
76+
77+ except Exception as e :
78+
79+ errors [obj ] = e
80+
81+ if not errors :
82+
83+ with open (output_fp , "w" ) as fp :
84+ fp .write (csv_str )
85+
86+ if notify_user :
87+ notify (f"Data exported to:\n \n { Path (output_fp ).absolute ()} \n " )
88+
89+ if errors :
90+
91+ print (errors )
92+ notify ("There were errors exporting data from some or all of the objects. See console." )
93+
94+
95+ def get_3D_mesh (series : Series , obj_name : str ) -> Union [Surface , Spheres , Contours ]:
96+ """Get mesh for an object."""
97+
98+ ## Create initial 3D obj
99+
100+ mode = series .getAttr (obj_name , "3D_mode" )
101+
102+ if mode == "surface" :
103+ obj_data = Surface (obj_name , series )
104+
105+ elif mode == "spheres" :
106+ obj_data = Spheres (obj_name , series )
107+
108+ elif mode == "contours" :
109+ obj_data = Contours (obj_name , series )
110+
111+ ## Iterate through sections and collect data
112+
113+ for snum , section in series .enumerateSections (show_progress = False ):
114+
115+ ## Assume somewhat uniform section thickness
116+ # tform = section.tform
117+
118+ if obj_name not in section .contours :
119+
120+ continue
121+
122+ ## Get alignment
123+ obj_alignment = series .getAttr (obj_name , "alignment" )
124+
125+ if not obj_alignment :
126+
127+ tform = section .tform
128+
129+ else :
130+
131+ tform = section .tforms [obj_alignment ]
132+
133+ for trace in section .contours [obj_name ]:
134+
135+ ## Collect all points if generating full surface
136+ obj_data .addTrace (trace , snum , tform )
137+
138+ return obj_data
87139
88140
89141def convert_vedo_to_tm (obj ) -> trimesh .Trimesh :
0 commit comments