New ReadFromPerl() method
This commit is contained in:
parent
bb656ea72c
commit
6373322b84
6 changed files with 137 additions and 78 deletions
|
@ -10,6 +10,38 @@ TriangleMesh::ReadSTLFile(char* input_file) {
|
||||||
stl_open(&stl, input_file);
|
stl_open(&stl, input_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TriangleMesh::ReadFromPerl(SV* vertices, SV* facets)
|
||||||
|
{
|
||||||
|
stl_initialize(&stl);
|
||||||
|
stl.stats.type = inmemory;
|
||||||
|
|
||||||
|
// count facets and allocate memory
|
||||||
|
AV* facets_av = (AV*)SvRV(facets);
|
||||||
|
stl.stats.number_of_facets = av_len(facets_av)+1;
|
||||||
|
stl.stats.original_num_facets = stl.stats.number_of_facets;
|
||||||
|
stl_allocate(&stl);
|
||||||
|
|
||||||
|
// read geometry
|
||||||
|
AV* vertices_av = (AV*)SvRV(vertices);
|
||||||
|
for (unsigned int i = 0; i < stl.stats.number_of_facets; i++) {
|
||||||
|
AV* facet_av = (AV*)SvRV(*av_fetch(facets_av, i, 0));
|
||||||
|
stl_facet facet;
|
||||||
|
facet.normal.x = NULL;
|
||||||
|
facet.normal.y = NULL;
|
||||||
|
facet.normal.z = NULL;
|
||||||
|
for (unsigned int v = 0; v <= 2; v++) {
|
||||||
|
AV* vertex_av = (AV*)SvRV(*av_fetch(vertices_av, SvIV(*av_fetch(facet_av, v, 0)), 0));
|
||||||
|
facet.vertex[v].x = SvNV(*av_fetch(vertex_av, 0, 0));
|
||||||
|
facet.vertex[v].y = SvNV(*av_fetch(vertex_av, 1, 0));
|
||||||
|
facet.vertex[v].z = SvNV(*av_fetch(vertex_av, 2, 0));
|
||||||
|
}
|
||||||
|
facet.extra[0] = NULL;
|
||||||
|
facet.extra[1] = NULL;
|
||||||
|
|
||||||
|
stl.facet_start[i] = facet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TriangleMesh::Repair() {
|
TriangleMesh::Repair() {
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -13,6 +13,7 @@ class TriangleMesh
|
||||||
TriangleMesh();
|
TriangleMesh();
|
||||||
~TriangleMesh();
|
~TriangleMesh();
|
||||||
void ReadSTLFile(char* input_file);
|
void ReadSTLFile(char* input_file);
|
||||||
|
void ReadFromPerl(SV* vertices, SV* facets);
|
||||||
void Repair();
|
void Repair();
|
||||||
void WriteOBJFile(char* output_file);
|
void WriteOBJFile(char* output_file);
|
||||||
AV* ToPerl();
|
AV* ToPerl();
|
||||||
|
|
|
@ -55,7 +55,7 @@ typedef struct
|
||||||
}stl_facet;
|
}stl_facet;
|
||||||
#define SIZEOF_STL_FACET 50
|
#define SIZEOF_STL_FACET 50
|
||||||
|
|
||||||
typedef enum {binary, ascii} stl_type;
|
typedef enum {binary, ascii, inmemory} stl_type;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -172,3 +172,11 @@ extern void stl_calculate_normal(float normal[], stl_facet *facet);
|
||||||
extern void stl_normalize_vector(float v[]);
|
extern void stl_normalize_vector(float v[]);
|
||||||
extern void stl_calculate_volume(stl_file *stl);
|
extern void stl_calculate_volume(stl_file *stl);
|
||||||
|
|
||||||
|
extern void stl_initialize(stl_file *stl);
|
||||||
|
static void stl_count_facets(stl_file *stl, char *file);
|
||||||
|
extern void stl_allocate(stl_file *stl);
|
||||||
|
static void stl_read(stl_file *stl, int first_facet, int first);
|
||||||
|
static void stl_facet_stats(stl_file *stl, stl_facet facet, int first);
|
||||||
|
static void stl_reallocate(stl_file *stl);
|
||||||
|
static int stl_get_little_int(FILE *fp);
|
||||||
|
static float stl_get_little_float(FILE *fp);
|
||||||
|
|
|
@ -31,17 +31,11 @@
|
||||||
#define SEEK_END 2
|
#define SEEK_END 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void stl_initialize(stl_file *stl, char *file);
|
|
||||||
static void stl_allocate(stl_file *stl);
|
|
||||||
static void stl_read(stl_file *stl, int first_facet, int first);
|
|
||||||
static void stl_reallocate(stl_file *stl);
|
|
||||||
static int stl_get_little_int(FILE *fp);
|
|
||||||
static float stl_get_little_float(FILE *fp);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
stl_open(stl_file *stl, char *file)
|
stl_open(stl_file *stl, char *file)
|
||||||
{
|
{
|
||||||
stl_initialize(stl, file);
|
stl_initialize(stl);
|
||||||
|
stl_count_facets(stl, file);
|
||||||
stl_allocate(stl);
|
stl_allocate(stl);
|
||||||
stl_read(stl, 0, 1);
|
stl_read(stl, 0, 1);
|
||||||
fclose(stl->fp);
|
fclose(stl->fp);
|
||||||
|
@ -75,17 +69,9 @@ stl_get_little_float(FILE *fp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
stl_initialize(stl_file *stl, char *file)
|
stl_initialize(stl_file *stl)
|
||||||
{
|
{
|
||||||
long file_size;
|
|
||||||
int header_num_facets;
|
|
||||||
int num_facets;
|
|
||||||
int i, j;
|
|
||||||
unsigned char chtest[128];
|
|
||||||
int num_lines = 1;
|
|
||||||
char *error_msg;
|
|
||||||
|
|
||||||
stl->stats.degenerate_facets = 0;
|
stl->stats.degenerate_facets = 0;
|
||||||
stl->stats.edges_fixed = 0;
|
stl->stats.edges_fixed = 0;
|
||||||
stl->stats.facets_added = 0;
|
stl->stats.facets_added = 0;
|
||||||
|
@ -101,7 +87,18 @@ stl_initialize(stl_file *stl, char *file)
|
||||||
stl->facet_start = NULL;
|
stl->facet_start = NULL;
|
||||||
stl->v_indices = NULL;
|
stl->v_indices = NULL;
|
||||||
stl->v_shared = NULL;
|
stl->v_shared = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stl_count_facets(stl_file *stl, char *file)
|
||||||
|
{
|
||||||
|
long file_size;
|
||||||
|
int header_num_facets;
|
||||||
|
int num_facets;
|
||||||
|
int i, j;
|
||||||
|
unsigned char chtest[128];
|
||||||
|
int num_lines = 1;
|
||||||
|
char *error_msg;
|
||||||
|
|
||||||
/* Open the file */
|
/* Open the file */
|
||||||
stl->fp = fopen(file, "r");
|
stl->fp = fopen(file, "r");
|
||||||
|
@ -189,7 +186,7 @@ stl_initialize(stl_file *stl, char *file)
|
||||||
stl->stats.original_num_facets = stl->stats.number_of_facets;
|
stl->stats.original_num_facets = stl->stats.number_of_facets;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
stl_allocate(stl_file *stl)
|
stl_allocate(stl_file *stl)
|
||||||
{
|
{
|
||||||
/* Allocate memory for the entire .STL file */
|
/* Allocate memory for the entire .STL file */
|
||||||
|
@ -210,7 +207,8 @@ stl_open_merge(stl_file *stl, char *file)
|
||||||
int first_facet;
|
int first_facet;
|
||||||
|
|
||||||
first_facet = stl->stats.number_of_facets;
|
first_facet = stl->stats.number_of_facets;
|
||||||
stl_initialize(stl, file);
|
stl_initialize(stl);
|
||||||
|
stl_count_facets(stl, file);
|
||||||
stl_reallocate(stl);
|
stl_reallocate(stl);
|
||||||
stl_read(stl, first_facet, 0);
|
stl_read(stl, first_facet, 0);
|
||||||
}
|
}
|
||||||
|
@ -236,11 +234,6 @@ stl_read(stl_file *stl, int first_facet, int first)
|
||||||
{
|
{
|
||||||
stl_facet facet;
|
stl_facet facet;
|
||||||
int i;
|
int i;
|
||||||
float diff_x;
|
|
||||||
float diff_y;
|
|
||||||
float diff_z;
|
|
||||||
float max_diff;
|
|
||||||
|
|
||||||
|
|
||||||
if(stl->stats.type == binary)
|
if(stl->stats.type == binary)
|
||||||
{
|
{
|
||||||
|
@ -291,12 +284,30 @@ stl_read(stl_file *stl, int first_facet, int first)
|
||||||
/* Write the facet into memory. */
|
/* Write the facet into memory. */
|
||||||
stl->facet_start[i] = facet;
|
stl->facet_start[i] = facet;
|
||||||
|
|
||||||
|
stl_facet_stats(stl, facet, first);
|
||||||
|
}
|
||||||
|
stl->stats.size.x = stl->stats.max.x - stl->stats.min.x;
|
||||||
|
stl->stats.size.y = stl->stats.max.y - stl->stats.min.y;
|
||||||
|
stl->stats.size.z = stl->stats.max.z - stl->stats.min.z;
|
||||||
|
stl->stats.bounding_diameter = sqrt(
|
||||||
|
stl->stats.size.x * stl->stats.size.x +
|
||||||
|
stl->stats.size.y * stl->stats.size.y +
|
||||||
|
stl->stats.size.z * stl->stats.size.z
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
stl_facet_stats(stl_file *stl, stl_facet facet, int first)
|
||||||
|
{
|
||||||
|
float diff_x;
|
||||||
|
float diff_y;
|
||||||
|
float diff_z;
|
||||||
|
float max_diff;
|
||||||
/* while we are going through all of the facets, let's find the */
|
/* while we are going through all of the facets, let's find the */
|
||||||
/* maximum and minimum values for x, y, and z */
|
/* maximum and minimum values for x, y, and z */
|
||||||
|
|
||||||
/* Initialize the max and min values the first time through*/
|
/* Initialize the max and min values the first time through*/
|
||||||
if(first)
|
if (first) {
|
||||||
{
|
|
||||||
stl->stats.max.x = facet.vertex[0].x;
|
stl->stats.max.x = facet.vertex[0].x;
|
||||||
stl->stats.min.x = facet.vertex[0].x;
|
stl->stats.min.x = facet.vertex[0].x;
|
||||||
stl->stats.max.y = facet.vertex[0].y;
|
stl->stats.max.y = facet.vertex[0].y;
|
||||||
|
@ -313,6 +324,7 @@ stl_read(stl_file *stl, int first_facet, int first)
|
||||||
|
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now find the max and min values */
|
/* now find the max and min values */
|
||||||
stl->stats.max.x = STL_MAX(stl->stats.max.x, facet.vertex[0].x);
|
stl->stats.max.x = STL_MAX(stl->stats.max.x, facet.vertex[0].x);
|
||||||
stl->stats.min.x = STL_MIN(stl->stats.min.x, facet.vertex[0].x);
|
stl->stats.min.x = STL_MIN(stl->stats.min.x, facet.vertex[0].x);
|
||||||
|
@ -335,15 +347,6 @@ stl_read(stl_file *stl, int first_facet, int first)
|
||||||
stl->stats.max.z = STL_MAX(stl->stats.max.z, facet.vertex[2].z);
|
stl->stats.max.z = STL_MAX(stl->stats.max.z, facet.vertex[2].z);
|
||||||
stl->stats.min.z = STL_MIN(stl->stats.min.z, facet.vertex[2].z);
|
stl->stats.min.z = STL_MIN(stl->stats.min.z, facet.vertex[2].z);
|
||||||
}
|
}
|
||||||
stl->stats.size.x = stl->stats.max.x - stl->stats.min.x;
|
|
||||||
stl->stats.size.y = stl->stats.max.y - stl->stats.min.y;
|
|
||||||
stl->stats.size.z = stl->stats.max.z - stl->stats.min.z;
|
|
||||||
stl->stats.bounding_diameter =
|
|
||||||
sqrt(stl->stats.size.x * stl->stats.size.x +
|
|
||||||
stl->stats.size.y * stl->stats.size.y +
|
|
||||||
stl->stats.size.z * stl->stats.size.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
stl_close(stl_file *stl)
|
stl_close(stl_file *stl)
|
||||||
|
|
|
@ -4,9 +4,23 @@ use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Slic3r::XS;
|
use Slic3r::XS;
|
||||||
use Test::More tests => 1;
|
use Test::More tests => 3;
|
||||||
|
|
||||||
is Slic3r::TriangleMesh::XS::hello_world(), 'Hello world!',
|
is Slic3r::TriangleMesh::XS::hello_world(), 'Hello world!',
|
||||||
'hello world';
|
'hello world';
|
||||||
|
|
||||||
|
my $cube = {
|
||||||
|
vertices => [ [20,20,0], [20,0,0], [0,0,0], [0,20,0], [20,20,20], [0,20,20], [0,0,20], [20,0,20] ],
|
||||||
|
facets => [ [0,1,2], [0,2,3], [4,5,6], [4,6,7], [0,4,7], [0,7,1], [1,7,6], [1,6,2], [2,6,5], [2,5,3], [4,0,3], [4,3,5] ],
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
my $m = Slic3r::TriangleMesh::XS->new;
|
||||||
|
$m->ReadFromPerl($cube->{vertices}, $cube->{facets});
|
||||||
|
$m->Repair;
|
||||||
|
my ($vertices, $facets) = @{$m->ToPerl};
|
||||||
|
is_deeply $vertices, $cube->{vertices}, 'vertices arrayref roundtrip';
|
||||||
|
is_deeply $facets, $cube->{facets}, 'facets arrayref roundtrip';
|
||||||
|
}
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
TriangleMesh();
|
TriangleMesh();
|
||||||
~TriangleMesh();
|
~TriangleMesh();
|
||||||
void ReadSTLFile(char* input_file);
|
void ReadSTLFile(char* input_file);
|
||||||
|
void ReadFromPerl(SV* vertices, SV* facets);
|
||||||
void Repair();
|
void Repair();
|
||||||
void WriteOBJFile(char* output_file);
|
void WriteOBJFile(char* output_file);
|
||||||
AV* ToPerl();
|
AV* ToPerl();
|
||||||
|
|
Loading…
Reference in a new issue