@@ -138,7 +138,7 @@ class CSV_OT_ExportData(bpy.types.Operator):
138138 bl_idname = "csv.export_data"
139139 bl_label = "Export CSV"
140140 bl_options = {"REGISTER" , "UNDO" }
141- bl_description = "Export an empty CSV file at the specified path "
141+ bl_description = "Export mesh attribute data to CSV file "
142142
143143 def execute (self , context ):
144144 scene = context .scene
@@ -163,17 +163,64 @@ def execute(self, context):
163163 return {"CANCELLED" }
164164
165165 try :
166- # Create an empty CSV file with basic header
167- with open (export_path , 'w' , newline = '' , encoding = 'utf-8' ) as csvfile :
168- writer = csv .writer (csvfile )
169- # Write a basic header row
170- writer .writerow (['x' , 'y' , 'z' ])
166+ import databpy as db
167+ import polars as pl
171168
172- self .report ({"INFO" }, f"Empty CSV file created at: { export_path } for object: { export_object .name } " )
169+ # Evaluate the object and get mesh data
170+ evaluated_obj = db .evaluate_object (export_object )
171+ mesh = evaluated_obj .to_mesh ()
172+
173+ # Collect all attribute data
174+ attribute_data = {}
175+ for attr in mesh .attributes :
176+ if attr .name not in {'sharp_face' , 'UVMap' } and not attr .name .startswith ('.' ):
177+ a = db .named_attribute (evaluated_obj , attr .name )
178+ attribute_data [attr .name ] = a
179+
180+ # Create polars DataFrame
181+ df = pl .DataFrame (attribute_data )
182+
183+ # Sort columns so "position" is first
184+ if "position" in df .columns :
185+ column_order = ["position" ] + [col for col in df .columns if col != "position" ]
186+ df = df .select (column_order )
187+
188+ # Check dtypes and expand array columns
189+ dtypes = df .dtypes
190+ array_columns = []
191+ expanded_df = df .clone ()
192+
193+ for i , dtype in enumerate (dtypes ):
194+ col_name = df .columns [i ]
195+ if str (dtype ).startswith ('Array' ):
196+ array_columns .append (col_name )
197+
198+ # Get the array length from the first non-null value
199+ first_array = expanded_df .select (pl .col (col_name )).item (0 , 0 )
200+ array_length = len (first_array )
201+
202+ # Expand array into separate columns with indexed names
203+ for j in range (array_length ):
204+ expanded_df = expanded_df .with_columns ([
205+ pl .col (col_name ).arr .get (j ).alias (f"{ col_name } { j + 1 } " )
206+ ])
207+ # Drop the original array column
208+ expanded_df = expanded_df .drop (col_name )
209+
210+ # Reorder columns to place position columns first
211+ position_columns = [col for col in expanded_df .columns if col .startswith ('position' )]
212+ other_columns = [col for col in expanded_df .columns if not col .startswith ('position' )]
213+ column_order = position_columns + other_columns
214+ expanded_df = expanded_df .select (column_order )
215+
216+ # Write to CSV file
217+ expanded_df .write_csv (export_path )
218+
219+ self .report ({"INFO" }, f"CSV file exported to: { export_path } for object: { export_object .name } ({ len (expanded_df )} rows, { len (expanded_df .columns )} columns)" )
173220 return {"FINISHED" }
174221
175222 except Exception as e :
176- self .report ({"ERROR" }, f"Failed to create CSV file: { e } " )
223+ self .report ({"ERROR" }, f"Failed to export CSV file: { e } " )
177224 return {"CANCELLED" }
178225
179226
0 commit comments