I have recently been doing significant work with processing 3D meshes and associated textures. Today I have extracted the Wavefront OBJ parser I’m using into a seperate library and posted the code for others to use.
https://github.com/stefangordon/ObjParser
If you are not familiar with the Obj spec, this is a great reference:
http://www.martinreddy.net/gfx/3d/OBJ.spec
Usage
The main entry point to the library is via the Obj class. Parsing and writing files is very simple.
1 2 3 4 5 6 7 8 |
// Initialize var obj = new Obj(); // Read Wavefront OBJ file obj.LoadObj([input path]); // Write OBJ file obj.WriteObjFile([output path]); |
When an OBJ file is loaded all of its faces, vertices, and UV’s are accessible to you in IEnumerables of types Face, Vertex, and TextureVertex. All of these elemental types are based on IType, so adding support for additional parts of the OBJ format is quite simple.
You can use this library as a start to basic mesh manipulation. For example, cropping a mesh is as simple as removing all vertices and faces outside of a specific boundary, and updating indexes appropriately, then writing the file back out.
I had to change source to
success = double.TryParse(data[1], NumberStyles.Any, culture, out x);
coz I’m from another notation system 😉
I have OBJ definition like the following one. I got exception “Could not parse parameter as int” in Face.LoadFromStringArray(). I’m not using any textures, so I think it must be omitted, right?
v -0.5 -0.5 0.5
v 0.5 -0.5 0.5
v 0.5 -0.5 -0.5
v -0.5 -0.5 -0.5
v -0.5 0.5 0.5
v 0.5 0.5 0.5
v 0.5 0.5 -0.5
v -0.5 0.5 -0.5
f 4//1 3//2 2//3 1//4
f 2//5 6//6 5//7 1//8
f 3//9 7//10 6//11 2//12
f 8//13 7//14 3//15 4//16
f 5//17 8//18 4//19 1//20
f 6//21 7//22 8//23 5//24
Yes the face parser needs a small upgrade I think. The “for” loop around line 32 of typesface.cs is designed to parse the individual components of the face, but it is only designed to handle V/VT or V, where as you have V//VN.
The spec is V/VT/VN so probably we should look at position 1 and 2 of the resulting split array and if 1 parses we store it in VT. We can optionally add a normals array and start storing VN also.
Feel free to file an issue on the github repo (this will remind me to fix it) or submit a pull request if you fix it. Thanks!
Dear Stefan,
First, thanks for your code.
I noticed all the texture vertices (“vt” s) are 0 0 when I write out the OBJ file.
I’m trying to fix this in the TextureVertex.cs file but not making any head way.
Any ideas?
Many thanks,
Ghetz
Its OK now, fixed it.
hi
thanks for your code man
I would like to draw my obj file in sharpGl any idea how can I ? thnaks
Hi there and thank you for your lib!
Can you suggest a proper way of merging map tiles, represented as .obj in order to create bigger tile.
I load tiles one by one into one .obj
https://hastebin.com/xasasahayi.cs
but when i viewing generated .obj it do show only one tile (first one loaded).
I assume this is because of tiles offsets not set properly, tho i do not know Wavefront structure good enough yet to understand how those should be calculated and vertexes\faces to be changed
If you can suggest maybe links where to rad about how this can be done, i would be grateful, thank you!
Ok, i got how Wavefront objects structure logic works 🙂
here is example of merging 9 tiles (center + 8 neighbors) into one:
https://hastebin.com/unufeviset.cs
maybe you will consider adding this function (or similar) to your github
Great! I will copy that code into some github issues so it is not lost.
Are texture names parsed at all? Kinda curious since I have a project I’ve been trying to do that involved getting the textures from each material and reading them.
After you parse the file the path to the referenced MTL will be in the Mtl string property. Typically if there is an image texture that would be in the MTL file, so you’d need to then pop that file open and look for it. Spec: http://paulbourke.net/dataformats/mtl/