## Background We attempted to add OBJ file import/export support in PR #7, which was closed pending fixes. This issue documents the current state and what needs to be done. ## What Was Done ### Initial Implementation - Created custom OBJ parser for import (478 lines) - Created custom OBJ exporter (359 lines) - Both were functional with the custom implementation ### Refactor Based on Feedback After feedback that the project should use Three.js's built-in loaders/exporters (since we already use Three.js for rendering): 1. **Export**: Discovered the app was already using Three.js OBJExporter (`three/examples/jsm/exporters/OBJExporter.js`) in `src/utils/three-export.ts` line 165. The custom exporter was dead code and was removed. 2. **Import**: Refactored from custom parser to Three.js OBJLoader (`three/examples/jsm/loaders/OBJLoader.js`) ## Current Status ### Working ✅ - OBJ Export via Three.js OBJExporter ### Not Working ❌ - OBJ Import has issues after refactor to Three.js OBJLoader ## Known Issues with OBJ Import 1. **Fixed**: Function signature mismatch - `createMeshFromGeometry()` expects `(name, vertices, faces)` but was being called with `(vertices, faces)` 2. **Potential issues** (need investigation): - Geometry conversion from Three.js BufferGeometry to our internal format - Normal computation if OBJ file doesn't include normals - Handling of OBJ files with/without UV coordinates - Group/object hierarchy processing ## Files Involved - `src/utils/obj-importer.ts` - Main import logic (219 lines after refactor) - `src/utils/three-export.ts` - Export logic (already using Three.js) - `src/features/menu/components/menu-bar.tsx` - Menu integration ## Tradeoffs of Using Three.js Loaders ### Pros - Battle-tested on thousands of OBJ files - Handles edge cases and malformed files - Supports material libraries (MTL) - Less code to maintain (~750 lines removed) - Consistent with GLTF import approach ### Cons - Triangulates quads (but WebGL requires triangles anyway) - Extra conversion step from Three.js format to our internal format ## What Needs to Be Done 1. Debug why imported OBJ meshes aren't rendering properly 2. Test with various OBJ files (with/without normals, UVs, materials) 3. Remove debug console.log statements once working 4. Ensure proper error handling and user feedback 5. Test that export still works correctly 6. Add test file(s) for validation ## Test Files The repo includes `pumpkin_tall_10k.obj` (326KB) for testing. ## Related Code for Reference The GLTF importer (`src/utils/gltf-importer.ts`) successfully uses the same pattern: - Uses Three.js GLTFLoader - Converts via `buildGeometryFromThreeGeometry()` function - Same conversion approach should work for OBJ ## Notes The last commit with debug logging (09e8106) adds extensive console output to help diagnose where the import process fails. After reviewing the original custom OBJ importer (commit a8308c7), it handled all the cases mentioned as "potential issues": Geometry Conversion Created vertices directly in our format with proper vertex deduplication based on unique (position, normal, uv) combinations: const getVertexKey = (vIdx: number, nIdx?: number, uvIdx?: number) => { return `${vIdx}_${nIdx ?? 'none'}_${uvIdx ?? 'none'}`; }; Normal Computation Handled missing normals by calculating them after mesh creation: if (objNormals.length === 0) { mesh.vertices = calculateVertexNormals(mesh); } UV Coordinates Provided default UVs when missing: const uv = uvIdx !== undefined ? objUVs[uvIdx] : vec2(0, 0); Group/Object Hierarchy - Parsed 'o' and 'g' commands for object/group definitions - Created a root group for all imported objects - Maintained object separation from the OBJ file Triangulation Handled all polygon types: - Triangles: used as-is - Quads: split into 2 triangles - N-gons: fan triangulation from first vertex The Challenge The refactor to Three.js OBJLoader should theoretically be simpler since Three.js handles these cases internally. However, we need to ensure: 1. Three.js OBJLoader is processing the geometry correctly 2. We're properly extracting the processed data from Three.js format 3. The conversion from BufferGeometry maintains the same robustness as our custom implementation The custom implementation was comprehensive (478 lines) but the Three.js approach should be more maintainable (219 lines) if we can get it working with the same robustness.