Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/xs
diff options
context:
space:
mode:
authorAlessandro Ranellucci <aar@cpan.org>2013-07-03 13:38:01 +0400
committerAlessandro Ranellucci <aar@cpan.org>2013-07-03 13:38:01 +0400
commit6373322b84ea151feba667c964e9e5fd6eac25fc (patch)
treedf5b931f30c5aac9365d7490e2fe074a2394401d /xs
parentbb656ea72c5e9aa6260fe93616a75986153f795b (diff)
New ReadFromPerl() method
Diffstat (limited to 'xs')
-rw-r--r--xs/src/TriangleMesh.cpp32
-rw-r--r--xs/src/TriangleMesh.hpp1
-rw-r--r--xs/src/admesh/stl.h10
-rw-r--r--xs/src/admesh/stlinit.c155
-rw-r--r--xs/t/01_trianglemesh.t16
-rw-r--r--xs/xsp/TriangleMesh.xsp1
6 files changed, 137 insertions, 78 deletions
diff --git a/xs/src/TriangleMesh.cpp b/xs/src/TriangleMesh.cpp
index 7219f85fa..462a93347 100644
--- a/xs/src/TriangleMesh.cpp
+++ b/xs/src/TriangleMesh.cpp
@@ -10,6 +10,38 @@ TriangleMesh::ReadSTLFile(char* 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
TriangleMesh::Repair() {
int i;
diff --git a/xs/src/TriangleMesh.hpp b/xs/src/TriangleMesh.hpp
index e8cb5d3b6..78e62cf9a 100644
--- a/xs/src/TriangleMesh.hpp
+++ b/xs/src/TriangleMesh.hpp
@@ -13,6 +13,7 @@ class TriangleMesh
TriangleMesh();
~TriangleMesh();
void ReadSTLFile(char* input_file);
+ void ReadFromPerl(SV* vertices, SV* facets);
void Repair();
void WriteOBJFile(char* output_file);
AV* ToPerl();
diff --git a/xs/src/admesh/stl.h b/xs/src/admesh/stl.h
index 92f14000f..1cfe5f2bc 100644
--- a/xs/src/admesh/stl.h
+++ b/xs/src/admesh/stl.h
@@ -55,7 +55,7 @@ typedef struct
}stl_facet;
#define SIZEOF_STL_FACET 50
-typedef enum {binary, ascii} stl_type;
+typedef enum {binary, ascii, inmemory} stl_type;
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_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);
diff --git a/xs/src/admesh/stlinit.c b/xs/src/admesh/stlinit.c
index cd6a8e074..7d8b9e65a 100644
--- a/xs/src/admesh/stlinit.c
+++ b/xs/src/admesh/stlinit.c
@@ -31,17 +31,11 @@
#define SEEK_END 2
#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
stl_open(stl_file *stl, char *file)
{
- stl_initialize(stl, file);
+ stl_initialize(stl);
+ stl_count_facets(stl, file);
stl_allocate(stl);
stl_read(stl, 0, 1);
fclose(stl->fp);
@@ -75,17 +69,9 @@ stl_get_little_float(FILE *fp)
}
-static void
-stl_initialize(stl_file *stl, char *file)
+void
+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.edges_fixed = 0;
stl->stats.facets_added = 0;
@@ -101,8 +87,19 @@ stl_initialize(stl_file *stl, char *file)
stl->facet_start = NULL;
stl->v_indices = 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 */
stl->fp = fopen(file, "r");
if(stl->fp == NULL)
@@ -189,7 +186,7 @@ stl_initialize(stl_file *stl, char *file)
stl->stats.original_num_facets = stl->stats.number_of_facets;
}
-static void
+void
stl_allocate(stl_file *stl)
{
/* Allocate memory for the entire .STL file */
@@ -210,7 +207,8 @@ stl_open_merge(stl_file *stl, char *file)
int first_facet;
first_facet = stl->stats.number_of_facets;
- stl_initialize(stl, file);
+ stl_initialize(stl);
+ stl_count_facets(stl, file);
stl_reallocate(stl);
stl_read(stl, first_facet, 0);
}
@@ -236,12 +234,7 @@ stl_read(stl_file *stl, int first_facet, int first)
{
stl_facet facet;
int i;
- float diff_x;
- float diff_y;
- float diff_z;
- float max_diff;
-
if(stl->stats.type == binary)
{
fseek(stl->fp, HEADER_SIZE, SEEK_SET);
@@ -291,59 +284,69 @@ stl_read(stl_file *stl, int first_facet, int first)
/* Write the facet into memory. */
stl->facet_start[i] = facet;
- /* while we are going through all of the facets, let's find the */
- /* maximum and minimum values for x, y, and z */
-
- /* Initialize the max and min values the first time through*/
- if(first)
- {
- stl->stats.max.x = facet.vertex[0].x;
- stl->stats.min.x = facet.vertex[0].x;
- stl->stats.max.y = facet.vertex[0].y;
- stl->stats.min.y = facet.vertex[0].y;
- stl->stats.max.z = facet.vertex[0].z;
- stl->stats.min.z = facet.vertex[0].z;
-
- diff_x = ABS(facet.vertex[0].x - facet.vertex[1].x);
- diff_y = ABS(facet.vertex[0].y - facet.vertex[1].y);
- diff_z = ABS(facet.vertex[0].z - facet.vertex[1].z);
- max_diff = STL_MAX(diff_x, diff_y);
- max_diff = STL_MAX(diff_z, max_diff);
- stl->stats.shortest_edge = max_diff;
-
- first = 0;
- }
- /* now find the max and min values */
- 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.max.y = STL_MAX(stl->stats.max.y, facet.vertex[0].y);
- stl->stats.min.y = STL_MIN(stl->stats.min.y, facet.vertex[0].y);
- stl->stats.max.z = STL_MAX(stl->stats.max.z, facet.vertex[0].z);
- stl->stats.min.z = STL_MIN(stl->stats.min.z, facet.vertex[0].z);
-
- stl->stats.max.x = STL_MAX(stl->stats.max.x, facet.vertex[1].x);
- stl->stats.min.x = STL_MIN(stl->stats.min.x, facet.vertex[1].x);
- stl->stats.max.y = STL_MAX(stl->stats.max.y, facet.vertex[1].y);
- stl->stats.min.y = STL_MIN(stl->stats.min.y, facet.vertex[1].y);
- stl->stats.max.z = STL_MAX(stl->stats.max.z, facet.vertex[1].z);
- stl->stats.min.z = STL_MIN(stl->stats.min.z, facet.vertex[1].z);
-
- stl->stats.max.x = STL_MAX(stl->stats.max.x, facet.vertex[2].x);
- stl->stats.min.x = STL_MIN(stl->stats.min.x, facet.vertex[2].x);
- stl->stats.max.y = STL_MAX(stl->stats.max.y, facet.vertex[2].y);
- stl->stats.min.y = STL_MIN(stl->stats.min.y, facet.vertex[2].y);
- 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_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);
+ 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 */
+ /* maximum and minimum values for x, y, and z */
+
+ /* Initialize the max and min values the first time through*/
+ if (first) {
+ stl->stats.max.x = facet.vertex[0].x;
+ stl->stats.min.x = facet.vertex[0].x;
+ stl->stats.max.y = facet.vertex[0].y;
+ stl->stats.min.y = facet.vertex[0].y;
+ stl->stats.max.z = facet.vertex[0].z;
+ stl->stats.min.z = facet.vertex[0].z;
+
+ diff_x = ABS(facet.vertex[0].x - facet.vertex[1].x);
+ diff_y = ABS(facet.vertex[0].y - facet.vertex[1].y);
+ diff_z = ABS(facet.vertex[0].z - facet.vertex[1].z);
+ max_diff = STL_MAX(diff_x, diff_y);
+ max_diff = STL_MAX(diff_z, max_diff);
+ stl->stats.shortest_edge = max_diff;
+
+ first = 0;
+ }
+
+ /* now find the max and min values */
+ 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.max.y = STL_MAX(stl->stats.max.y, facet.vertex[0].y);
+ stl->stats.min.y = STL_MIN(stl->stats.min.y, facet.vertex[0].y);
+ stl->stats.max.z = STL_MAX(stl->stats.max.z, facet.vertex[0].z);
+ stl->stats.min.z = STL_MIN(stl->stats.min.z, facet.vertex[0].z);
+
+ stl->stats.max.x = STL_MAX(stl->stats.max.x, facet.vertex[1].x);
+ stl->stats.min.x = STL_MIN(stl->stats.min.x, facet.vertex[1].x);
+ stl->stats.max.y = STL_MAX(stl->stats.max.y, facet.vertex[1].y);
+ stl->stats.min.y = STL_MIN(stl->stats.min.y, facet.vertex[1].y);
+ stl->stats.max.z = STL_MAX(stl->stats.max.z, facet.vertex[1].z);
+ stl->stats.min.z = STL_MIN(stl->stats.min.z, facet.vertex[1].z);
+
+ stl->stats.max.x = STL_MAX(stl->stats.max.x, facet.vertex[2].x);
+ stl->stats.min.x = STL_MIN(stl->stats.min.x, facet.vertex[2].x);
+ stl->stats.max.y = STL_MAX(stl->stats.max.y, facet.vertex[2].y);
+ stl->stats.min.y = STL_MIN(stl->stats.min.y, facet.vertex[2].y);
+ 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);
+}
void
stl_close(stl_file *stl)
diff --git a/xs/t/01_trianglemesh.t b/xs/t/01_trianglemesh.t
index 97e98fcce..8d3c5dd0d 100644
--- a/xs/t/01_trianglemesh.t
+++ b/xs/t/01_trianglemesh.t
@@ -4,9 +4,23 @@ use strict;
use warnings;
use Slic3r::XS;
-use Test::More tests => 1;
+use Test::More tests => 3;
is Slic3r::TriangleMesh::XS::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__
diff --git a/xs/xsp/TriangleMesh.xsp b/xs/xsp/TriangleMesh.xsp
index 82aa55024..be0d5b25e 100644
--- a/xs/xsp/TriangleMesh.xsp
+++ b/xs/xsp/TriangleMesh.xsp
@@ -8,6 +8,7 @@
TriangleMesh();
~TriangleMesh();
void ReadSTLFile(char* input_file);
+ void ReadFromPerl(SV* vertices, SV* facets);
void Repair();
void WriteOBJFile(char* output_file);
AV* ToPerl();