With no cache:
$ time bin/dat2stl --ldrawdir=ldraw --file ldraw/parts/11295.dat > 11295.stl
real 0m1.857s
user 0m1.764s
sys 0m0.092s
$ time bin/dat2stl --ldrawdir=ldraw --file ldraw/parts/11295.dat > 11295.stl
real 0m1.834s
user 0m1.786s
sys 0m0.048s
With cache:
$ time bin/dat2stl --cache --ldrawdir=ldraw --file ldraw/parts/11295.dat > 11295.stl
real 0m1.084s
user 0m1.044s
sys 0m0.040s
$ time bin/dat2stl --cache --ldrawdir=ldraw --file ldraw/parts/11295.dat > 11295.stl
real 0m1.076s
user 0m1.028s
sys 0m0.048s
Before this commit it appeared that STL viewers could handle the output. However,
rendering the models in OpenGL revealed that the surface normals were all messed up. I
believe most STL viewers just don't care about surface normals, because I suppose they
don't really matter for 3d slicing.
The problem ended up being really a complex issue around the winding order of triangles in
sub-parts, and how this is affected by the "inversion" state. The winding order of
triangles in ldraw is a complex combination of BFC meta commands and transformation
matricies that "mirror" sub-parts. I tried to leave extensive comments in the code rather
than go into it in the commit message.
Also added a json output for rendering as OpenGL buffers. This is to help me debug issues
with the surface normals.
While working on this I also realized that the output of parsing a sub-part can be cached,
as long at the "invert" flag is part of the cache key. This could make a huge difference
in performance, because for example a "stud" gets generated many many times, and in this
version of the code that results in a lot of repeated processing.
I was concatenating paths together using the unix slash `/`. This change used
`File::Spec::catpath` instead, however I haven't been able to test it on Windows, and
there may be other path issues. Also note: without debugging on the user doesn't see when
files are not found (eg: due to path issues), so it silently creates an empty STL file.