@@ -87,39 +87,20 @@ module FastObj
87
87
end
88
88
elseif c == UInt8 (' f' )
89
89
# Face
90
- face = Int[]
91
- face_tex = Int[]
92
- face_norm = Int[]
90
+ faces, face_texcoords, face_normals = parse_face (parser)
91
+ println (" Parsed face data:" )
92
+ println (" Faces: $faces " )
93
+ println (" Face texcoords: $face_texcoords " )
94
+ println (" Face normals: $face_normals " )
93
95
94
- # Parse face indices
95
- while parser. pos <= length (parser. data) && ! isspace (Char (parser. data[parser. pos]))
96
- # Vertex index
97
- v_idx = parse_int (parser)
98
- push! (face, v_idx)
99
-
100
- # Check for texture coordinate and normal
101
- if parser. pos <= length (parser. data) && parser. data[parser. pos] == UInt8 (' /' )
102
- parser. pos += 1
103
- if parser. pos <= length (parser. data) && parser. data[parser. pos] != UInt8 (' /' )
104
- t_idx = parse_int (parser)
105
- push! (face_tex, t_idx)
106
- end
107
-
108
- if parser. pos <= length (parser. data) && parser. data[parser. pos] == UInt8 (' /' )
109
- parser. pos += 1
110
- n_idx = parse_int (parser)
111
- push! (face_norm, n_idx)
112
- end
113
- end
114
- end
115
-
116
- if ! isempty (face)
117
- push! (parser. faces, face)
118
- if ! isempty (face_tex)
119
- push! (parser. face_texcoords, face_tex)
96
+ # Add all faces to the parser
97
+ for i in 1 : length (faces)
98
+ push! (parser. faces, faces[i])
99
+ if i <= length (face_texcoords)
100
+ push! (parser. face_texcoords, face_texcoords[i])
120
101
end
121
- if ! isempty (face_norm )
122
- push! (parser. face_normals, face_norm )
102
+ if i <= length (face_normals )
103
+ push! (parser. face_normals, face_normals[i] )
123
104
end
124
105
end
125
106
elseif c == UInt8 (' m' )
@@ -174,6 +155,14 @@ module FastObj
174
155
parser. pos += 1
175
156
end
176
157
158
+ println (" Final parser results:" )
159
+ println (" Vertices: $(length (parser. vertices)) " )
160
+ println (" Normals: $(length (parser. normals)) " )
161
+ println (" Texcoords: $(length (parser. texcoords)) " )
162
+ println (" Faces: $(length (parser. faces)) " )
163
+ println (" Face texcoords: $(length (parser. face_texcoords)) " )
164
+ println (" Face normals: $(length (parser. face_normals)) " )
165
+
177
166
return parser. vertices, parser. normals, parser. texcoords, parser. faces,
178
167
parser. face_texcoords, parser. face_normals, parser. materials
179
168
end
@@ -196,18 +185,26 @@ module FastObj
196
185
return parse (Float64, num_str)
197
186
end
198
187
199
- function parse_int (parser:: FastObjParser ):: Int
188
+ function parse_int (parser:: FastObjParser ):: Union{ Int, Nothing}
200
189
# Skip whitespace
201
190
while parser. pos <= length (parser. data) && isspace (Char (parser. data[parser. pos]))
202
191
parser. pos += 1
203
192
end
204
193
194
+ if parser. pos > length (parser. data)
195
+ return nothing
196
+ end
197
+
205
198
# Find the end of the number
206
199
end_pos = parser. pos
207
200
while end_pos <= length (parser. data) && ! isspace (Char (parser. data[end_pos])) && parser. data[end_pos] != UInt8 (' /' )
208
201
end_pos += 1
209
202
end
210
203
204
+ if end_pos == parser. pos
205
+ return nothing
206
+ end
207
+
211
208
# Parse the number
212
209
num_str = String (parser. data[parser. pos: end_pos- 1 ])
213
210
parser. pos = end_pos
@@ -292,4 +289,105 @@ module FastObj
292
289
293
290
close (f)
294
291
end
292
+
293
+ function parse_face (parser:: FastObjParser ):: Tuple{Vector{Vector{Int}}, Vector{Vector{Int}}, Vector{Vector{Int}}}
294
+ faces = Vector {Vector{Int}} ()
295
+ face_texcoords = Vector {Vector{Int}} ()
296
+ face_normals = Vector {Vector{Int}} ()
297
+
298
+ # Skip whitespace before face definition
299
+ while parser. pos <= length (parser. data) && isspace (Char (parser. data[parser. pos]))
300
+ parser. pos += 1
301
+ end
302
+
303
+ if parser. pos > length (parser. data)
304
+ return faces, face_texcoords, face_normals
305
+ end
306
+
307
+ # Parse all vertices for this face
308
+ vertices = Int[]
309
+ texcoords = Int[]
310
+ normals = Int[]
311
+
312
+ while parser. pos <= length (parser. data) && ! isspace (Char (parser. data[parser. pos]))
313
+ # Parse vertex index
314
+ v_idx = parse_int (parser)
315
+ if v_idx === nothing
316
+ break
317
+ end
318
+
319
+ # Handle negative indices (relative to current position)
320
+ if v_idx < 0
321
+ v_idx = length (parser. vertices) + v_idx + 1
322
+ end
323
+
324
+ # Add vertex index
325
+ push! (vertices, v_idx)
326
+
327
+ # Check for texture coordinate and normal indices
328
+ if parser. pos <= length (parser. data) && parser. data[parser. pos] == UInt8 (' /' )
329
+ parser. pos += 1
330
+
331
+ # Parse texture coordinate index if present
332
+ if parser. pos <= length (parser. data) && ! isspace (Char (parser. data[parser. pos])) && parser. data[parser. pos] != UInt8 (' /' )
333
+ vt_idx = parse_int (parser)
334
+ if vt_idx != = nothing
335
+ if vt_idx < 0
336
+ vt_idx = length (parser. texcoords) + vt_idx + 1
337
+ end
338
+ push! (texcoords, vt_idx)
339
+ end
340
+ end
341
+
342
+ # Parse normal index if present
343
+ if parser. pos <= length (parser. data) && parser. data[parser. pos] == UInt8 (' /' )
344
+ parser. pos += 1
345
+ if parser. pos <= length (parser. data) && ! isspace (Char (parser. data[parser. pos]))
346
+ vn_idx = parse_int (parser)
347
+ if vn_idx != = nothing
348
+ if vn_idx < 0
349
+ vn_idx = length (parser. normals) + vn_idx + 1
350
+ end
351
+ push! (normals, vn_idx)
352
+ end
353
+ end
354
+ end
355
+ end
356
+ end
357
+
358
+ println (" Parsed face with $(length (vertices)) vertices" )
359
+ println (" Vertex indices: $vertices " )
360
+ println (" Texture coordinate indices: $texcoords " )
361
+ println (" Normal indices: $normals " )
362
+
363
+ # Triangulate the face using triangle fan approach
364
+ if length (vertices) >= 3
365
+ # For each vertex after the first two, create a triangle with the first vertex
366
+ for i in 2 : (length (vertices)- 1 )
367
+ # Create triangle using first vertex and current edge
368
+ triangle = [vertices[1 ], vertices[i], vertices[i+ 1 ]]
369
+ push! (faces, triangle)
370
+ println (" Created triangle: $triangle " )
371
+
372
+ # Add corresponding texture coordinates if available
373
+ if ! isempty (texcoords)
374
+ tex_triangle = [texcoords[1 ], texcoords[i], texcoords[i+ 1 ]]
375
+ push! (face_texcoords, tex_triangle)
376
+ println (" Added texture coordinates: $tex_triangle " )
377
+ end
378
+
379
+ # Add corresponding normals if available
380
+ if ! isempty (normals)
381
+ normal_triangle = [normals[1 ], normals[i], normals[i+ 1 ]]
382
+ push! (face_normals, normal_triangle)
383
+ println (" Added normal indices: $normal_triangle " )
384
+ end
385
+ end
386
+ else
387
+ @warn " Face has less than 3 vertices, skipping"
388
+ end
389
+
390
+ println (" Created $(length (faces)) triangles from face" )
391
+ return faces, face_texcoords, face_normals
392
+ end
295
393
end
0 commit comments