diff --git a/xs/src/admesh/connect.c b/xs/src/admesh/connect.c index 56ebfa1448..e9129d0079 100644 --- a/xs/src/admesh/connect.c +++ b/xs/src/admesh/connect.c @@ -82,6 +82,16 @@ stl_check_facets_exact(stl_file *stl) { for(i = 0; i < stl->stats.number_of_facets; i++) { facet = stl->facet_start[i]; + // Positive and negative zeros are possible in the floats, which are considered equal by the FP unit. + // When using a memcmp on raw floats, those numbers report to be different. + // Unify all +0 and -0 to +0 to make the floats equal under memcmp. + { + uint32_t *f = (uint32_t*)&facet; + for (int j = 0; j < 12; ++ j, ++ f) // 3x vertex + normal: 4x3 = 12 floats + if (*f == 0x80000000) + // Negative zero, switch to positive zero. + *f = 0; + } /* If any two of the three vertices are found to be exactally the same, call them degenerate and remove the facet. */ if( !memcmp(&facet.vertex[0], &facet.vertex[1], @@ -278,6 +288,16 @@ stl_check_facets_nearby(stl_file *stl, float tolerance) { for(i = 0; i < stl->stats.number_of_facets; i++) { facet = stl->facet_start[i]; + // Positive and negative zeros are possible in the floats, which are considered equal by the FP unit. + // When using a memcmp on raw floats, those numbers report to be different. + // Unify all +0 and -0 to +0 to make the floats equal under memcmp. + { + uint32_t *f = (uint32_t*)&facet; + for (int j = 0; j < 12; ++ j, ++ f) // 3x vertex + normal: 4x3 = 12 floats + if (*f == 0x80000000) + // Negative zero, switch to positive zero. + *f = 0; + } for(j = 0; j < 3; j++) { if(stl->neighbors_start[i].neighbor[j] == -1) { edge[j].facet_number = i; diff --git a/xs/src/admesh/stl.h b/xs/src/admesh/stl.h index 34e1907e70..1399836325 100644 --- a/xs/src/admesh/stl.h +++ b/xs/src/admesh/stl.h @@ -163,7 +163,7 @@ typedef struct { } stl_file; -extern void stl_open(stl_file *stl, char *file); +extern void stl_open(stl_file *stl, const char *file); extern void stl_close(stl_file *stl); extern void stl_stats_out(stl_file *stl, FILE *file, char *input_file); extern void stl_print_edges(stl_file *stl, FILE *file); @@ -196,6 +196,7 @@ extern void stl_rotate_z(stl_file *stl, float angle); extern void stl_mirror_xy(stl_file *stl); extern void stl_mirror_yz(stl_file *stl); extern void stl_mirror_xz(stl_file *stl); +extern void stl_transform(stl_file *stl, float *trafo3x4); extern void stl_open_merge(stl_file *stl, char *file); extern void stl_invalidate_shared_vertices(stl_file *stl); extern void stl_generate_shared_vertices(stl_file *stl); @@ -210,7 +211,7 @@ extern void stl_calculate_volume(stl_file *stl); extern void stl_repair(stl_file *stl, int fixall_flag, int exact_flag, int tolerance_flag, float tolerance, int increment_flag, float increment, int nearby_flag, int iterations, int remove_unconnected_flag, int fill_holes_flag, int normal_directions_flag, int normal_values_flag, int reverse_all_flag, int verbose_flag); extern void stl_initialize(stl_file *stl); -extern void stl_count_facets(stl_file *stl, char *file); +extern void stl_count_facets(stl_file *stl, const char *file); extern void stl_allocate(stl_file *stl); extern void stl_read(stl_file *stl, int first_facet, int first); extern void stl_facet_stats(stl_file *stl, stl_facet facet, int first); diff --git a/xs/src/admesh/stlinit.c b/xs/src/admesh/stlinit.c index 33293cd47c..f797004fb1 100644 --- a/xs/src/admesh/stlinit.c +++ b/xs/src/admesh/stlinit.c @@ -32,7 +32,7 @@ #endif void -stl_open(stl_file *stl, char *file) { +stl_open(stl_file *stl, const char *file) { stl_initialize(stl); stl_count_facets(stl, file); stl_allocate(stl); @@ -48,7 +48,7 @@ stl_initialize(stl_file *stl) { } void -stl_count_facets(stl_file *stl, char *file) { +stl_count_facets(stl_file *stl, const char *file) { long file_size; int header_num_facets; int num_facets; @@ -308,29 +308,6 @@ stl_read(stl_file *stl, int first_facet, int first) { printf("stl_read: facet %d.z = %e\r\n", j, facet.vertex[j].z); } #endif - -#if 1 - { - // Positive and negative zeros are possible in the floats, which are considered equal by the FP unit. - // When using a memcmp on raw floats, those numbers report to be different. - // Unify all +0 and -0 to +0 to make the floats equal under memcmp. - uint32_t *f = (uint32_t*)&facet; - for (int j = 0; j < 12; ++ j, ++ f) // 3x vertex + normal: 4x3 = 12 floats - if (*f == 0x80000000) - // Negative zero, switch to positive zero. - *f = 0; - } -#else - { - // Due to the nature of the floating point numbers, close to zero values may be represented with singificantly higher precision - // than the rest of the vertices. Round them to zero. - float *f = (float*)&facet; - for (int j = 0; j < 12; ++ j, ++ f) // 3x vertex + normal: 4x3 = 12 floats - if (*f > -1e-12f && *f < 1e-12f) - // Negative zero, switch to positive zero. - *f = 0; - } -#endif /* Write the facet into memory. */ memcpy(stl->facet_start+i, &facet, SIZEOF_STL_FACET); stl_facet_stats(stl, facet, first); diff --git a/xs/src/admesh/util.c b/xs/src/admesh/util.c index 4ecb76e799..cabb8a7783 100644 --- a/xs/src/admesh/util.c +++ b/xs/src/admesh/util.c @@ -185,6 +185,24 @@ static void calculate_normals(stl_file *stl) { } } +void stl_transform(stl_file *stl, float *trafo3x4) { + int i_face, i_vertex, i, j; + if (stl->error) + return; + for (i_face = 0; i_face < stl->stats.number_of_facets; ++ i_face) { + stl_vertex *vertices = stl->facet_start[i_face].vertex; + for (i_vertex = 0; i_vertex < 3; ++ i_vertex) { + stl_vertex &v_dst = vertices[i_vertex]; + stl_vertex v_src = v_dst; + v_dst.x = trafo3x4[0] * v_src.x + trafo3x4[1] * v_src.y + trafo3x4[2] * v_src.z + trafo3x4[3]; + v_dst.y = trafo3x4[4] * v_src.x + trafo3x4[5] * v_src.y + trafo3x4[6] * v_src.z + trafo3x4[7]; + v_dst.z = trafo3x4[8] * v_src.x + trafo3x4[9] * v_src.y + trafo3x4[10] * v_src.z + trafo3x4[11]; + } + } + stl_get_size(stl); + calculate_normals(stl); +} + void stl_rotate_x(stl_file *stl, float angle) { int i;