1
0
mirror of https://github.com/kristov/ldraw2stl.git synced 2025-05-15 14:20:11 -07:00
ldraw2stl/bin/dat2stl
ceade 3b042dbb4e Introduce an optional cache
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
2025-03-22 13:29:00 +01:00

134 lines
3.4 KiB
Perl
Executable File

#!/usr/bin/perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use LDraw::Parser;
use Getopt::Long;
my $opts = {};
GetOptions(
$opts,
'help',
'scale=s',
'ldrawdir=s',
'file=s',
'debug',
'json',
'nomodel',
'invert',
'cache',
);
if (!keys %{$opts}) {
print_usage();
exit 0;
}
if ($opts->{help}) {
print_usage();
exit 0;
}
if (!$opts->{file}) {
print "ERROR: --file is required! (try --help)\n";
exit 1;
}
sub print_usage {
print <<END;
Usage: $0 --file <input file> [--scale=<N> --ldrawdir=/usr/share/ldraw]
Takes an ldraw part .dat file as input and converts it into an STL file.
--file <string>
The full path to the input .dat part file. Regardless of where this file
is, sub-parts of the file will be searched in --ldrawdir.
--scale <int>
Also scale the STL by N. This is separate from the LDU scaling that is
used to convert internally from LDU (LDraw Unit) to mm (STL).
--ldrawdir <string>
The location of the ldraw parts library package. Note: it is expected
that this contains the directories "p", "parts" and "models". The Debian
non-free package "ldraw-parts" installs to /usr/share/ldraw and that is
the default value for this tool.
--debug
Print debugging messages to STDERR
--json
Dump the model as a json object in the form:
{"normals":[],"vertexes":[]}
Note: the surface normal of the triangle is duplicated for each of the 3 vertexes
in the triangle, so these can be loaded into GL buffers and rendered with
glDrawArrays.
--nomodel
Do not print the stl output. I am using this to run the script over all
parts to try to detect issues.
--invert
Invert the part. Used for debugging.
--cache
Use a cache to avoid repeated geneneration of the same geometry. Many geometric
primitives are repeated (eg: a stud), and are simply translated into different
locations in the model. A combination of the sub-part name and the invert flag is
used to build a cache key to store the generated triangles for the sub-part. When
this is stable I will change this to --nocache so it's on by default.
END
}
my $parser_opts = {
file => $opts->{file},
};
if ($opts->{cache}) {
$parser_opts->{cache} = LDraw::Parser::Cache->new;
}
if ($opts->{scale}) {
$parser_opts->{scale} = $opts->{scale};
}
if ($opts->{ldrawdir}) {
$parser_opts->{ldraw_path} = $opts->{ldrawdir};
}
if ($opts->{debug}) {
$parser_opts->{debug} = 1;
}
if ($opts->{invert}) {
$parser_opts->{invert} = 1;
}
my $parser = LDraw::Parser->new($parser_opts);
$parser->parse;
if ($opts->{json}) {
my $data = $parser->gl_buffer;
print '{"normals":[';
print join(',', @{$data->{normals}});
print '],"vertexes":[';
print join(',', @{$data->{vertexes}});
print ']}';
print "\n";
exit 0;
}
if ($opts->{nomodel}) {
exit 0;
}
my $facets = $parser->stl_buffer;
printf("solid GiantLegoRocks\n");
for my $facet (@{$facets}) {
printf("facet normal %0.4f %0.4f %0.4f\n", @{$facet->{normal}});
printf(" outer loop\n");
for my $vertex (@{$facet->{vertexes}}) {
printf(" vertex %0.4f %0.4f %0.4f\n", @{$vertex});
}
printf(" endloop\n");
printf("endfacet\n");
}
printf("endsolid GiantLegoRocks\n");