mirror of
https://github.com/kristov/ldraw2stl.git
synced 2025-05-15 14:20:11 -07:00
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
134 lines
3.4 KiB
Perl
Executable File
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");
|