admesh refactoring: replaced various diagnostics outputs with boost::log

This commit is contained in:
bubnikv 2019-06-10 19:45:38 +02:00
parent 6defabea53
commit 313ec7424a
7 changed files with 405 additions and 481 deletions

View file

@ -28,6 +28,7 @@
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include <boost/log/trivial.hpp>
#include <boost/detail/endian.hpp> #include <boost/detail/endian.hpp>
#include "stl.h" #include "stl.h"
@ -124,7 +125,9 @@ struct HashTableEdges {
for (HashEdge *temp = this->heads[i]; this->heads[i] != this->tail; temp = this->heads[i]) { for (HashEdge *temp = this->heads[i]; this->heads[i] != this->tail; temp = this->heads[i]) {
this->heads[i] = this->heads[i]->next; this->heads[i] = this->heads[i]->next;
delete temp; delete temp;
#ifndef NDEBUG
++ this->freed; ++ this->freed;
#endif /* NDEBUG */
} }
} }
this->heads.clear(); this->heads.clear();
@ -139,7 +142,9 @@ struct HashTableEdges {
if (link == this->tail) { if (link == this->tail) {
// This list doesn't have any edges currently in it. Add this one. // This list doesn't have any edges currently in it. Add this one.
HashEdge *new_edge = new HashEdge(edge); HashEdge *new_edge = new HashEdge(edge);
#ifndef NDEBUG
++ this->malloced; ++ this->malloced;
#endif /* NDEBUG */
new_edge->next = this->tail; new_edge->next = this->tail;
this->heads[chain_number] = new_edge; this->heads[chain_number] = new_edge;
} else if (edges_equal(edge, *link)) { } else if (edges_equal(edge, *link)) {
@ -148,18 +153,24 @@ struct HashTableEdges {
// Delete the matched edge from the list. // Delete the matched edge from the list.
this->heads[chain_number] = link->next; this->heads[chain_number] = link->next;
delete link; delete link;
#ifndef NDEBUG
++ this->freed; ++ this->freed;
#endif /* NDEBUG */
} else { } else {
// Continue through the rest of the list. // Continue through the rest of the list.
for (;;) { for (;;) {
if (link->next == this->tail) { if (link->next == this->tail) {
// This is the last item in the list. Insert a new edge. // This is the last item in the list. Insert a new edge.
HashEdge *new_edge = new HashEdge; HashEdge *new_edge = new HashEdge;
#ifndef NDEBUG
++ this->malloced; ++ this->malloced;
#endif /* NDEBUG */
*new_edge = edge; *new_edge = edge;
new_edge->next = this->tail; new_edge->next = this->tail;
link->next = new_edge; link->next = new_edge;
#ifndef NDEBUG
++ this->collisions; ++ this->collisions;
#endif /* NDEBUG */
break; break;
} }
if (edges_equal(edge, *link->next)) { if (edges_equal(edge, *link->next)) {
@ -169,12 +180,16 @@ struct HashTableEdges {
HashEdge *temp = link->next; HashEdge *temp = link->next;
link->next = link->next->next; link->next = link->next->next;
delete temp; delete temp;
#ifndef NDEBUG
++ this->freed; ++ this->freed;
#endif /* NDEBUG */
break; break;
} }
// This is not a match. Go to the next link. // This is not a match. Go to the next link.
link = link->next; link = link->next;
#ifndef NDEBUG
++ this->collisions; ++ this->collisions;
#endif /* NDEBUG */
} }
} }
} }
@ -184,9 +199,11 @@ struct HashTableEdges {
HashEdge* tail; HashEdge* tail;
int M; int M;
#ifndef NDEBUG
size_t malloced = 0; size_t malloced = 0;
size_t freed = 0; size_t freed = 0;
size_t collisions = 0; size_t collisions = 0;
#endif /* NDEBUG */
private: private:
static inline size_t hash_size_from_nr_faces(const size_t nr_faces) static inline size_t hash_size_from_nr_faces(const size_t nr_faces)
@ -366,7 +383,7 @@ static void match_neighbors_nearby(stl_file *stl, const HashEdge &edge_a, const
if (facet_num == first_facet) { if (facet_num == first_facet) {
// back to the beginning // back to the beginning
printf("Back to the first facet changing vertices: probably a mobius part.\nTry using a smaller tolerance or don't do a nearby check\n"); BOOST_LOG_TRIVIAL(info) << "Back to the first facet changing vertices: probably a mobius part. Try using a smaller tolerance or don't do a nearby check.";
return; return;
} }
} }
@ -506,7 +523,7 @@ void stl_remove_unconnected_facets(stl_file *stl)
if (neighbors.neighbor[i] != -1) { if (neighbors.neighbor[i] != -1) {
int &other_face_idx = stl->neighbors_start[neighbors.neighbor[i]].neighbor[(neighbors.which_vertex_not[i] + 1) % 3]; int &other_face_idx = stl->neighbors_start[neighbors.neighbor[i]].neighbor[(neighbors.which_vertex_not[i] + 1) % 3];
if (other_face_idx != stl->stats.number_of_facets) { if (other_face_idx != stl->stats.number_of_facets) {
printf("in remove_facet: neighbor = %d numfacets = %d this is wrong\n", other_face_idx, stl->stats.number_of_facets); BOOST_LOG_TRIVIAL(info) << "in remove_facet: neighbor = " << other_face_idx << " numfacets = " << stl->stats.number_of_facets << " this is wrong";
return; return;
} }
other_face_idx = facet_number; other_face_idx = facet_number;
@ -697,7 +714,7 @@ void stl_fill_holes(stl_file *stl)
if (facet_num == first_facet) { if (facet_num == first_facet) {
// back to the beginning // back to the beginning
printf("Back to the first facet filling holes: probably a mobius part.\nTry using a smaller tolerance or don't do a nearby check\n"); BOOST_LOG_TRIVIAL(info) << "Back to the first facet filling holes: probably a mobius part. Try using a smaller tolerance or don't do a nearby check.";
return; return;
} }
} }

View file

@ -25,6 +25,7 @@
#include <vector> #include <vector>
#include <boost/log/trivial.hpp>
#include <boost/nowide/cstdio.hpp> #include <boost/nowide/cstdio.hpp>
#include "stl.h" #include "stl.h"
@ -129,10 +130,7 @@ bool its_write_off(const indexed_triangle_set &its, const char *file)
/* Open the file */ /* Open the file */
FILE *fp = boost::nowide::fopen(file, "w"); FILE *fp = boost::nowide::fopen(file, "w");
if (fp == nullptr) { if (fp == nullptr) {
char *error_msg = (char*)malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */ BOOST_LOG_TRIVIAL(error) << "stl_write_ascii: Couldn't open " << file << " for writing";
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing", file);
perror(error_msg);
free(error_msg);
return false; return false;
} }
@ -151,10 +149,7 @@ bool its_write_vrml(const indexed_triangle_set &its, const char *file)
/* Open the file */ /* Open the file */
FILE *fp = boost::nowide::fopen(file, "w"); FILE *fp = boost::nowide::fopen(file, "w");
if (fp == nullptr) { if (fp == nullptr) {
char *error_msg = (char*)malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */ BOOST_LOG_TRIVIAL(error) << "stl_write_vrml: Couldn't open " << file << " for writing";
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing", file);
perror(error_msg);
free(error_msg);
return false; return false;
} }
@ -196,10 +191,7 @@ bool its_write_obj(const indexed_triangle_set &its, const char *file)
FILE *fp = boost::nowide::fopen(file, "w"); FILE *fp = boost::nowide::fopen(file, "w");
if (fp == nullptr) { if (fp == nullptr) {
char* error_msg = (char*)malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */ BOOST_LOG_TRIVIAL(error) << "stl_write_obj: Couldn't open " << file << " for writing";
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing", file);
perror(error_msg);
free(error_msg);
return false; return false;
} }

View file

@ -242,7 +242,7 @@ inline bool stl_vertex_lower(const stl_vertex &a, const stl_vertex &b) {
} }
extern void stl_calculate_volume(stl_file *stl); 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_repair(stl_file *stl, bool fixall_flag, bool exact_flag, bool tolerance_flag, float tolerance, bool increment_flag, float increment, bool nearby_flag, int iterations, bool remove_unconnected_flag, bool fill_holes_flag, bool normal_directions_flag, bool normal_values_flag, bool reverse_all_flag, bool verbose_flag);
extern void stl_reset(stl_file *stl); extern void stl_reset(stl_file *stl);
extern void stl_allocate(stl_file *stl); extern void stl_allocate(stl_file *stl);

View file

@ -24,6 +24,7 @@
#include <string.h> #include <string.h>
#include "stl.h" #include "stl.h"
#include <boost/log/trivial.hpp>
#include <boost/nowide/cstdio.hpp> #include <boost/nowide/cstdio.hpp>
#include <boost/detail/endian.hpp> #include <boost/detail/endian.hpp>
@ -107,65 +108,47 @@ Normals fixed : %5d\n", stl->stats.normals_fixed);
bool stl_write_ascii(stl_file *stl, const char *file, const char *label) bool stl_write_ascii(stl_file *stl, const char *file, const char *label)
{ {
char *error_msg; FILE *fp = boost::nowide::fopen(file, "w");
if (fp == NULL) {
BOOST_LOG_TRIVIAL(error) << "stl_write_ascii: Couldn't open " << file << " for writing";
return false;
}
/* Open the file */ fprintf(fp, "solid %s\n", label);
FILE *fp = boost::nowide::fopen(file, "w");
if(fp == NULL) {
error_msg = (char*)
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing",
file);
perror(error_msg);
free(error_msg);
return false;
}
fprintf(fp, "solid %s\n", label); for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
fprintf(fp, " facet normal % .8E % .8E % .8E\n",
stl->facet_start[i].normal(0), stl->facet_start[i].normal(1),
stl->facet_start[i].normal(2));
fprintf(fp, " outer loop\n");
fprintf(fp, " vertex % .8E % .8E % .8E\n",
stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1),
stl->facet_start[i].vertex[0](2));
fprintf(fp, " vertex % .8E % .8E % .8E\n",
stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1),
stl->facet_start[i].vertex[1](2));
fprintf(fp, " vertex % .8E % .8E % .8E\n",
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1),
stl->facet_start[i].vertex[2](2));
fprintf(fp, " endloop\n");
fprintf(fp, " endfacet\n");
}
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) { fprintf(fp, "endsolid %s\n", label);
fprintf(fp, " facet normal % .8E % .8E % .8E\n", fclose(fp);
stl->facet_start[i].normal(0), stl->facet_start[i].normal(1), return true;
stl->facet_start[i].normal(2));
fprintf(fp, " outer loop\n");
fprintf(fp, " vertex % .8E % .8E % .8E\n",
stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1),
stl->facet_start[i].vertex[0](2));
fprintf(fp, " vertex % .8E % .8E % .8E\n",
stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1),
stl->facet_start[i].vertex[1](2));
fprintf(fp, " vertex % .8E % .8E % .8E\n",
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1),
stl->facet_start[i].vertex[2](2));
fprintf(fp, " endloop\n");
fprintf(fp, " endfacet\n");
}
fprintf(fp, "endsolid %s\n", label);
fclose(fp);
return true;
} }
bool stl_print_neighbors(stl_file *stl, char *file) bool stl_print_neighbors(stl_file *stl, char *file)
{ {
FILE *fp; FILE *fp = boost::nowide::fopen(file, "w");
char *error_msg; if (fp == NULL) {
BOOST_LOG_TRIVIAL(error) << "stl_print_neighbors: Couldn't open " << file << " for writing";
return false;
}
/* Open the file */ for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
fp = boost::nowide::fopen(file, "w"); fprintf(fp, "%d, %d,%d, %d,%d, %d,%d\n",
if(fp == NULL) {
error_msg = (char*)
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
sprintf(error_msg, "stl_print_neighbors: Couldn't open %s for writing",
file);
perror(error_msg);
free(error_msg);
return false;
}
for (uint32_t i = 0; i < stl->stats.number_of_facets; i++) {
fprintf(fp, "%d, %d,%d, %d,%d, %d,%d\n",
i, i,
stl->neighbors_start[i].neighbor[0], stl->neighbors_start[i].neighbor[0],
(int)stl->neighbors_start[i].which_vertex_not[0], (int)stl->neighbors_start[i].which_vertex_not[0],
@ -173,62 +156,54 @@ bool stl_print_neighbors(stl_file *stl, char *file)
(int)stl->neighbors_start[i].which_vertex_not[1], (int)stl->neighbors_start[i].which_vertex_not[1],
stl->neighbors_start[i].neighbor[2], stl->neighbors_start[i].neighbor[2],
(int)stl->neighbors_start[i].which_vertex_not[2]); (int)stl->neighbors_start[i].which_vertex_not[2]);
} }
fclose(fp); fclose(fp);
return true; return true;
} }
#ifndef BOOST_LITTLE_ENDIAN #ifndef BOOST_LITTLE_ENDIAN
// Swap a buffer of 32bit data from little endian to big endian and vice versa. // Swap a buffer of 32bit data from little endian to big endian and vice versa.
void stl_internal_reverse_quads(char *buf, size_t cnt) void stl_internal_reverse_quads(char *buf, size_t cnt)
{ {
for (size_t i = 0; i < cnt; i += 4) { for (size_t i = 0; i < cnt; i += 4) {
std::swap(buf[i], buf[i+3]); std::swap(buf[i], buf[i+3]);
std::swap(buf[i+1], buf[i+2]); std::swap(buf[i+1], buf[i+2]);
} }
} }
#endif #endif
bool stl_write_binary(stl_file *stl, const char *file, const char *label) bool stl_write_binary(stl_file *stl, const char *file, const char *label)
{ {
FILE *fp; FILE *fp = boost::nowide::fopen(file, "wb");
char *error_msg; if (fp == NULL) {
BOOST_LOG_TRIVIAL(error) << "stl_write_binary: Couldn't open " << file << " for writing";
return false;
}
/* Open the file */ fprintf(fp, "%s", label);
fp = boost::nowide::fopen(file, "wb"); for (size_t i = strlen(label); i < LABEL_SIZE; ++ i)
if(fp == NULL) { putc(0, fp);
error_msg = (char*)
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
sprintf(error_msg, "stl_write_binary: Couldn't open %s for writing",
file);
perror(error_msg);
free(error_msg);
return false;
}
fprintf(fp, "%s", label); fseek(fp, LABEL_SIZE, SEEK_SET);
for(size_t i = strlen(label); i < LABEL_SIZE; i++) putc(0, fp);
fseek(fp, LABEL_SIZE, SEEK_SET);
#ifdef BOOST_LITTLE_ENDIAN #ifdef BOOST_LITTLE_ENDIAN
fwrite(&stl->stats.number_of_facets, 4, 1, fp); fwrite(&stl->stats.number_of_facets, 4, 1, fp);
for (const stl_facet &facet : stl->facet_start) for (const stl_facet &facet : stl->facet_start)
fwrite(&facet, SIZEOF_STL_FACET, 1, fp); fwrite(&facet, SIZEOF_STL_FACET, 1, fp);
#else /* BOOST_LITTLE_ENDIAN */ #else /* BOOST_LITTLE_ENDIAN */
char buffer[50]; char buffer[50];
// Convert the number of facets to little endian. // Convert the number of facets to little endian.
memcpy(buffer, &stl->stats.number_of_facets, 4); memcpy(buffer, &stl->stats.number_of_facets, 4);
stl_internal_reverse_quads(buffer, 4); stl_internal_reverse_quads(buffer, 4);
fwrite(buffer, 4, 1, fp); fwrite(buffer, 4, 1, fp);
for (i = 0; i < stl->stats.number_of_facets; ++ i) { for (i = 0; i < stl->stats.number_of_facets; ++ i) {
memcpy(buffer, stl->facet_start + i, 50); memcpy(buffer, stl->facet_start + i, 50);
// Convert to little endian. // Convert to little endian.
stl_internal_reverse_quads(buffer, 48); stl_internal_reverse_quads(buffer, 48);
fwrite(buffer, SIZEOF_STL_FACET, 1, fp); fwrite(buffer, SIZEOF_STL_FACET, 1, fp);
} }
#endif /* BOOST_LITTLE_ENDIAN */ #endif /* BOOST_LITTLE_ENDIAN */
fclose(fp); fclose(fp);
return true; return true;
} }
void stl_write_vertex(stl_file *stl, int facet, int vertex) void stl_write_vertex(stl_file *stl, int facet, int vertex)
@ -260,53 +235,39 @@ void stl_write_neighbor(stl_file *stl, int facet)
bool stl_write_quad_object(stl_file *stl, char *file) bool stl_write_quad_object(stl_file *stl, char *file)
{ {
FILE *fp; stl_vertex connect_color = stl_vertex::Zero();
char *error_msg; stl_vertex uncon_1_color = stl_vertex::Zero();
stl_vertex connect_color = stl_vertex::Zero(); stl_vertex uncon_2_color = stl_vertex::Zero();
stl_vertex uncon_1_color = stl_vertex::Zero(); stl_vertex uncon_3_color = stl_vertex::Zero();
stl_vertex uncon_2_color = stl_vertex::Zero(); stl_vertex color;
stl_vertex uncon_3_color = stl_vertex::Zero();
stl_vertex color;
/* Open the file */ FILE *fp = boost::nowide::fopen(file, "w");
fp = boost::nowide::fopen(file, "w"); if (fp == NULL) {
if(fp == NULL) { BOOST_LOG_TRIVIAL(error) << "stl_write_quad_object: Couldn't open " << file << " for writing";
error_msg = (char*) return false;
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */ }
sprintf(error_msg, "stl_write_quad_object: Couldn't open %s for writing",
file);
perror(error_msg);
free(error_msg);
return false;
}
fprintf(fp, "CQUAD\n"); fprintf(fp, "CQUAD\n");
for (uint32_t i = 0; i < stl->stats.number_of_facets; i++) { for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
int j = ((stl->neighbors_start[i].neighbor[0] == -1) + switch (stl->neighbors_start[i].num_neighbors_missing()) {
(stl->neighbors_start[i].neighbor[1] == -1) + case 0: color = connect_color; break;
(stl->neighbors_start[i].neighbor[2] == -1)); case 1: color = uncon_1_color; break;
if(j == 0) { case 2: color = uncon_2_color; break;
color = connect_color; default: color = uncon_3_color;
} else if(j == 1) { }
color = uncon_1_color; fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
} else if(j == 2) {
color = uncon_2_color;
} else {
color = uncon_3_color;
}
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](0),
stl->facet_start[i].vertex[0](1), stl->facet_start[i].vertex[0](1),
stl->facet_start[i].vertex[0](2), color(0), color(1), color(2)); stl->facet_start[i].vertex[0](2), color(0), color(1), color(2));
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n", fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](0),
stl->facet_start[i].vertex[1](1), stl->facet_start[i].vertex[1](1),
stl->facet_start[i].vertex[1](2), color(0), color(1), color(2)); stl->facet_start[i].vertex[1](2), color(0), color(1), color(2));
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n", fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](0),
stl->facet_start[i].vertex[2](1), stl->facet_start[i].vertex[2](1),
stl->facet_start[i].vertex[2](2), color(0), color(1), color(2)); stl->facet_start[i].vertex[2](2), color(0), color(1), color(2));
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n", fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](0),
stl->facet_start[i].vertex[2](1), stl->facet_start[i].vertex[2](1),
stl->facet_start[i].vertex[2](2), color(0), color(1), color(2)); stl->facet_start[i].vertex[2](2), color(0), color(1), color(2));
@ -317,47 +278,37 @@ bool stl_write_quad_object(stl_file *stl, char *file)
bool stl_write_dxf(stl_file *stl, const char *file, char *label) bool stl_write_dxf(stl_file *stl, const char *file, char *label)
{ {
FILE *fp; FILE *fp = boost::nowide::fopen(file, "w");
char *error_msg; if (fp == NULL) {
BOOST_LOG_TRIVIAL(error) << "stl_write_quad_object: Couldn't open " << file << " for writing";
return false;
}
/* Open the file */ fprintf(fp, "999\n%s\n", label);
fp = boost::nowide::fopen(file, "w"); fprintf(fp, "0\nSECTION\n2\nHEADER\n0\nENDSEC\n");
if(fp == NULL) { fprintf(fp, "0\nSECTION\n2\nTABLES\n0\nTABLE\n2\nLAYER\n70\n1\n\
error_msg = (char*) 0\nLAYER\n2\n0\n70\n0\n62\n7\n6\nCONTINUOUS\n0\nENDTAB\n0\nENDSEC\n");
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */ fprintf(fp, "0\nSECTION\n2\nBLOCKS\n0\nENDSEC\n");
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing",
file);
perror(error_msg);
free(error_msg);
return false;
}
fprintf(fp, "999\n%s\n", label); fprintf(fp, "0\nSECTION\n2\nENTITIES\n");
fprintf(fp, "0\nSECTION\n2\nHEADER\n0\nENDSEC\n");
fprintf(fp, "0\nSECTION\n2\nTABLES\n0\nTABLE\n2\nLAYER\n70\n1\n\
0\nLAYER\n2\n0\n70\n0\n62\n7\n6\nCONTINUOUS\n0\nENDTAB\n0\nENDSEC\n");
fprintf(fp, "0\nSECTION\n2\nBLOCKS\n0\nENDSEC\n");
fprintf(fp, "0\nSECTION\n2\nENTITIES\n"); for (uint32_t i = 0; i < stl->stats.number_of_facets; i++) {
fprintf(fp, "0\n3DFACE\n8\n0\n");
fprintf(fp, "10\n%f\n20\n%f\n30\n%f\n",
stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1),
stl->facet_start[i].vertex[0](2));
fprintf(fp, "11\n%f\n21\n%f\n31\n%f\n",
stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1),
stl->facet_start[i].vertex[1](2));
fprintf(fp, "12\n%f\n22\n%f\n32\n%f\n",
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1),
stl->facet_start[i].vertex[2](2));
fprintf(fp, "13\n%f\n23\n%f\n33\n%f\n",
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1),
stl->facet_start[i].vertex[2](2));
}
for (uint32_t i = 0; i < stl->stats.number_of_facets; i++) { fprintf(fp, "0\nENDSEC\n0\nEOF\n");
fprintf(fp, "0\n3DFACE\n8\n0\n"); fclose(fp);
fprintf(fp, "10\n%f\n20\n%f\n30\n%f\n", return true;
stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1),
stl->facet_start[i].vertex[0](2));
fprintf(fp, "11\n%f\n21\n%f\n31\n%f\n",
stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1),
stl->facet_start[i].vertex[1](2));
fprintf(fp, "12\n%f\n22\n%f\n32\n%f\n",
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1),
stl->facet_start[i].vertex[2](2));
fprintf(fp, "13\n%f\n23\n%f\n33\n%f\n",
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1),
stl->facet_start[i].vertex[2](2));
}
fprintf(fp, "0\nENDSEC\n0\nEOF\n");
fclose(fp);
return true;
} }

View file

@ -26,6 +26,7 @@
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
#include <boost/log/trivial.hpp>
#include <boost/nowide/cstdio.hpp> #include <boost/nowide/cstdio.hpp>
#include <boost/detail/endian.hpp> #include <boost/detail/endian.hpp>
@ -37,118 +38,102 @@
static FILE* stl_open_count_facets(stl_file *stl, const char *file) static FILE* stl_open_count_facets(stl_file *stl, const char *file)
{ {
long file_size; // Open the file in binary mode first.
uint32_t header_num_facets; FILE *fp = boost::nowide::fopen(file, "rb");
uint32_t num_facets; if (fp == nullptr) {
int i; BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: Couldn't open " << file << " for reading";
size_t s; return nullptr;
unsigned char chtest[128]; }
int num_lines = 1; // Find size of file.
char *error_msg; fseek(fp, 0, SEEK_END);
long file_size = ftell(fp);
/* Open the file in binary mode first */ // Check for binary or ASCII file.
FILE *fp = boost::nowide::fopen(file, "rb"); fseek(fp, HEADER_SIZE, SEEK_SET);
if (fp == nullptr) { unsigned char chtest[128];
error_msg = (char*) if (! fread(chtest, sizeof(chtest), 1, fp)) {
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */ BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: The input is an empty file: " << file;
sprintf(error_msg, "stl_initialize: Couldn't open %s for reading", fclose(fp);
file); return nullptr;
perror(error_msg); }
free(error_msg); stl->stats.type = ascii;
return nullptr; for (size_t s = 0; s < sizeof(chtest); s++) {
} if (chtest[s] > 127) {
/* Find size of file */ stl->stats.type = binary;
fseek(fp, 0, SEEK_END); break;
file_size = ftell(fp); }
}
rewind(fp);
/* Check for binary or ASCII file */ uint32_t num_facets = 0;
fseek(fp, HEADER_SIZE, SEEK_SET);
if (!fread(chtest, sizeof(chtest), 1, fp)) {
perror("The input is an empty file");
fclose(fp);
return nullptr;
}
stl->stats.type = ascii;
for(s = 0; s < sizeof(chtest); s++) {
if(chtest[s] > 127) {
stl->stats.type = binary;
break;
}
}
rewind(fp);
/* Get the header and the number of facets in the .STL file */ // Get the header and the number of facets in the .STL file.
/* If the .STL file is binary, then do the following */ // If the .STL file is binary, then do the following:
if(stl->stats.type == binary) { if (stl->stats.type == binary) {
/* Test if the STL file has the right size */ // Test if the STL file has the right size.
if(((file_size - HEADER_SIZE) % SIZEOF_STL_FACET != 0) if (((file_size - HEADER_SIZE) % SIZEOF_STL_FACET != 0) || (file_size < STL_MIN_FILE_SIZE)) {
|| (file_size < STL_MIN_FILE_SIZE)) { BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: The file " << file << " has the wrong size.";
fprintf(stderr, "The file %s has the wrong size.\n", file); fclose(fp);
fclose(fp); return nullptr;
return nullptr; }
} num_facets = (file_size - HEADER_SIZE) / SIZEOF_STL_FACET;
num_facets = (file_size - HEADER_SIZE) / SIZEOF_STL_FACET;
/* Read the header */ // Read the header.
if (fread(stl->stats.header, LABEL_SIZE, 1, fp) > 79) { if (fread(stl->stats.header, LABEL_SIZE, 1, fp) > 79)
stl->stats.header[80] = '\0'; stl->stats.header[80] = '\0';
}
/* Read the int following the header. This should contain # of facets */ // Read the int following the header. This should contain # of facets.
bool header_num_faces_read = fread(&header_num_facets, sizeof(uint32_t), 1, fp) != 0; uint32_t header_num_facets;
bool header_num_faces_read = fread(&header_num_facets, sizeof(uint32_t), 1, fp) != 0;
#ifndef BOOST_LITTLE_ENDIAN #ifndef BOOST_LITTLE_ENDIAN
// Convert from little endian to big endian. // Convert from little endian to big endian.
stl_internal_reverse_quads((char*)&header_num_facets, 4); stl_internal_reverse_quads((char*)&header_num_facets, 4);
#endif /* BOOST_LITTLE_ENDIAN */ #endif /* BOOST_LITTLE_ENDIAN */
if (! header_num_faces_read || num_facets != header_num_facets) { if (! header_num_faces_read || num_facets != header_num_facets)
fprintf(stderr, BOOST_LOG_TRIVIAL(info) << "stl_open_count_facets: Warning: File size doesn't match number of facets in the header: " << file;
"Warning: File size doesn't match number of facets in the header\n"); }
} // Otherwise, if the .STL file is ASCII, then do the following:
} else
/* Otherwise, if the .STL file is ASCII, then do the following */ {
else { // Reopen the file in text mode (for getting correct newlines on Windows)
/* Reopen the file in text mode (for getting correct newlines on Windows) */ // fix to silence a warning about unused return value.
// fix to silence a warning about unused return value. // obviously if it fails we have problems....
// obviously if it fails we have problems.... fp = boost::nowide::freopen(file, "r", fp);
fp = boost::nowide::freopen(file, "r", fp);
// do another null check to be safe // do another null check to be safe
if(fp == nullptr) { if (fp == nullptr) {
error_msg = (char*) BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: Couldn't open " << file << " for reading";
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */ fclose(fp);
sprintf(error_msg, "stl_initialize: Couldn't open %s for reading", return nullptr;
file); }
perror(error_msg);
free(error_msg);
fclose(fp);
return nullptr;
}
/* Find the number of facets */ // Find the number of facets.
char linebuf[100]; char linebuf[100];
while (fgets(linebuf, 100, fp) != nullptr) { int num_lines = 1;
/* don't count short lines */ while (fgets(linebuf, 100, fp) != nullptr) {
if (strlen(linebuf) <= 4) continue; // Don't count short lines.
if (strlen(linebuf) <= 4)
/* skip solid/endsolid lines as broken STL file generators may put several of them */ continue;
if (strncmp(linebuf, "solid", 5) == 0 || strncmp(linebuf, "endsolid", 8) == 0) continue; // Skip solid/endsolid lines as broken STL file generators may put several of them.
if (strncmp(linebuf, "solid", 5) == 0 || strncmp(linebuf, "endsolid", 8) == 0)
++num_lines; continue;
} ++ num_lines;
}
rewind(fp);
/* Get the header */
for(i = 0;
(i < 80) && (stl->stats.header[i] = getc(fp)) != '\n'; i++);
stl->stats.header[i] = '\0'; /* Lose the '\n' */
stl->stats.header[80] = '\0';
num_facets = num_lines / ASCII_LINES_PER_FACET; rewind(fp);
}
stl->stats.number_of_facets += num_facets; // Get the header.
stl->stats.original_num_facets = stl->stats.number_of_facets; int i = 0;
return fp; for (; i < 80 && (stl->stats.header[i] = getc(fp)) != '\n'; ++ i) ;
stl->stats.header[i] = '\0'; // Lose the '\n'
stl->stats.header[80] = '\0';
num_facets = num_lines / ASCII_LINES_PER_FACET;
}
stl->stats.number_of_facets += num_facets;
stl->stats.original_num_facets = stl->stats.number_of_facets;
return fp;
} }
/* Reads the contents of the file pointed to by fp into the stl structure, /* Reads the contents of the file pointed to by fp into the stl structure,
@ -156,85 +141,82 @@ static FILE* stl_open_count_facets(stl_file *stl, const char *file)
time running this for the stl and therefore we should reset our max and min stats. */ time running this for the stl and therefore we should reset our max and min stats. */
static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first) static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first)
{ {
stl_facet facet; if (stl->stats.type == binary)
fseek(fp, HEADER_SIZE, SEEK_SET);
else
rewind(fp);
if(stl->stats.type == binary) { char normal_buf[3][32];
fseek(fp, HEADER_SIZE, SEEK_SET); for (uint32_t i = first_facet; i < stl->stats.number_of_facets; ++i) {
} else { stl_facet facet;
rewind(fp);
}
char normal_buf[3][32]; if (stl->stats.type == binary) {
for(uint32_t i = first_facet; i < stl->stats.number_of_facets; i++) { // Read a single facet from a binary .STL file. We assume little-endian architecture!
if(stl->stats.type == binary) if (fread(&facet, 1, SIZEOF_STL_FACET, fp) != SIZEOF_STL_FACET)
/* Read a single facet from a binary .STL file */ return false;
{
/* we assume little-endian architecture! */
if (fread(&facet, 1, SIZEOF_STL_FACET, fp) != SIZEOF_STL_FACET)
return false;
#ifndef BOOST_LITTLE_ENDIAN #ifndef BOOST_LITTLE_ENDIAN
// Convert the loaded little endian data to big endian. // Convert the loaded little endian data to big endian.
stl_internal_reverse_quads((char*)&facet, 48); stl_internal_reverse_quads((char*)&facet, 48);
#endif /* BOOST_LITTLE_ENDIAN */ #endif /* BOOST_LITTLE_ENDIAN */
} else } else {
/* Read a single facet from an ASCII .STL file */ // Read a single facet from an ASCII .STL file
{ // skip solid/endsolid
// skip solid/endsolid // (in this order, otherwise it won't work when they are paired in the middle of a file)
// (in this order, otherwise it won't work when they are paired in the middle of a file) fscanf(fp, "endsolid%*[^\n]\n");
fscanf(fp, "endsolid%*[^\n]\n"); fscanf(fp, "solid%*[^\n]\n"); // name might contain spaces so %*s doesn't work and it also can be empty (just "solid")
fscanf(fp, "solid%*[^\n]\n"); // name might contain spaces so %*s doesn't work and it also can be empty (just "solid") // Leading space in the fscanf format skips all leading white spaces including numerous new lines and tabs.
// Leading space in the fscanf format skips all leading white spaces including numerous new lines and tabs. int res_normal = fscanf(fp, " facet normal %31s %31s %31s", normal_buf[0], normal_buf[1], normal_buf[2]);
int res_normal = fscanf(fp, " facet normal %31s %31s %31s", normal_buf[0], normal_buf[1], normal_buf[2]); assert(res_normal == 3);
assert(res_normal == 3); int res_outer_loop = fscanf(fp, " outer loop");
int res_outer_loop = fscanf(fp, " outer loop"); assert(res_outer_loop == 0);
assert(res_outer_loop == 0); int res_vertex1 = fscanf(fp, " vertex %f %f %f", &facet.vertex[0](0), &facet.vertex[0](1), &facet.vertex[0](2));
int res_vertex1 = fscanf(fp, " vertex %f %f %f", &facet.vertex[0](0), &facet.vertex[0](1), &facet.vertex[0](2)); assert(res_vertex1 == 3);
assert(res_vertex1 == 3); int res_vertex2 = fscanf(fp, " vertex %f %f %f", &facet.vertex[1](0), &facet.vertex[1](1), &facet.vertex[1](2));
int res_vertex2 = fscanf(fp, " vertex %f %f %f", &facet.vertex[1](0), &facet.vertex[1](1), &facet.vertex[1](2)); assert(res_vertex2 == 3);
assert(res_vertex2 == 3); int res_vertex3 = fscanf(fp, " vertex %f %f %f", &facet.vertex[2](0), &facet.vertex[2](1), &facet.vertex[2](2));
int res_vertex3 = fscanf(fp, " vertex %f %f %f", &facet.vertex[2](0), &facet.vertex[2](1), &facet.vertex[2](2)); assert(res_vertex3 == 3);
assert(res_vertex3 == 3); int res_endloop = fscanf(fp, " endloop");
int res_endloop = fscanf(fp, " endloop"); assert(res_endloop == 0);
assert(res_endloop == 0); // There is a leading and trailing white space around endfacet to eat up all leading and trailing white spaces including numerous tabs and new lines.
// There is a leading and trailing white space around endfacet to eat up all leading and trailing white spaces including numerous tabs and new lines. int res_endfacet = fscanf(fp, " endfacet ");
int res_endfacet = fscanf(fp, " endfacet "); if (res_normal != 3 || res_outer_loop != 0 || res_vertex1 != 3 || res_vertex2 != 3 || res_vertex3 != 3 || res_endloop != 0 || res_endfacet != 0) {
if (res_normal != 3 || res_outer_loop != 0 || res_vertex1 != 3 || res_vertex2 != 3 || res_vertex3 != 3 || res_endloop != 0 || res_endfacet != 0) { BOOST_LOG_TRIVIAL(error) << "Something is syntactically very wrong with this ASCII STL! ";
perror("Something is syntactically very wrong with this ASCII STL!"); return false;
return false; }
}
// The facet normal has been parsed as a single string as to workaround for not a numbers in the normal definition. // The facet normal has been parsed as a single string as to workaround for not a numbers in the normal definition.
if (sscanf(normal_buf[0], "%f", &facet.normal(0)) != 1 || if (sscanf(normal_buf[0], "%f", &facet.normal(0)) != 1 ||
sscanf(normal_buf[1], "%f", &facet.normal(1)) != 1 || sscanf(normal_buf[1], "%f", &facet.normal(1)) != 1 ||
sscanf(normal_buf[2], "%f", &facet.normal(2)) != 1) { sscanf(normal_buf[2], "%f", &facet.normal(2)) != 1) {
// Normal was mangled. Maybe denormals or "not a number" were stored? // Normal was mangled. Maybe denormals or "not a number" were stored?
// Just reset the normal and silently ignore it. // Just reset the normal and silently ignore it.
memset(&facet.normal, 0, sizeof(facet.normal)); memset(&facet.normal, 0, sizeof(facet.normal));
} }
} }
#if 0 #if 0
// Report close to zero vertex coordinates. Due to the nature of the floating point numbers, // Report close to zero vertex coordinates. 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. // close to zero values may be represented with singificantly higher precision than the rest of the vertices.
// It may be worth to round these numbers to zero during loading to reduce the number of errors reported // It may be worth to round these numbers to zero during loading to reduce the number of errors reported
// during the STL import. // during the STL import.
for (size_t j = 0; j < 3; ++ j) { for (size_t j = 0; j < 3; ++ j) {
if (facet.vertex[j](0) > -1e-12f && facet.vertex[j](0) < 1e-12f) if (facet.vertex[j](0) > -1e-12f && facet.vertex[j](0) < 1e-12f)
printf("stl_read: facet %d(0) = %e\r\n", j, facet.vertex[j](0)); printf("stl_read: facet %d(0) = %e\r\n", j, facet.vertex[j](0));
if (facet.vertex[j](1) > -1e-12f && facet.vertex[j](1) < 1e-12f) if (facet.vertex[j](1) > -1e-12f && facet.vertex[j](1) < 1e-12f)
printf("stl_read: facet %d(1) = %e\r\n", j, facet.vertex[j](1)); printf("stl_read: facet %d(1) = %e\r\n", j, facet.vertex[j](1));
if (facet.vertex[j](2) > -1e-12f && facet.vertex[j](2) < 1e-12f) if (facet.vertex[j](2) > -1e-12f && facet.vertex[j](2) < 1e-12f)
printf("stl_read: facet %d(2) = %e\r\n", j, facet.vertex[j](2)); printf("stl_read: facet %d(2) = %e\r\n", j, facet.vertex[j](2));
} }
#endif #endif
/* 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_facet_stats(stl, facet, first);
} }
stl->stats.size = stl->stats.max - stl->stats.min;
stl->stats.bounding_diameter = stl->stats.size.norm(); stl->stats.size = stl->stats.max - stl->stats.min;
return true; stl->stats.bounding_diameter = stl->stats.size.norm();
return true;
} }
bool stl_open(stl_file *stl, const char *file) bool stl_open(stl_file *stl, const char *file)
@ -277,21 +259,21 @@ void stl_reallocate(stl_file *stl)
void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first) void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first)
{ {
// 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
if (first) { if (first) {
// Initialize the max and min values the first time through // Initialize the max and min values the first time through
stl->stats.min = facet.vertex[0]; stl->stats.min = facet.vertex[0];
stl->stats.max = facet.vertex[0]; stl->stats.max = facet.vertex[0];
stl_vertex diff = (facet.vertex[1] - facet.vertex[0]).cwiseAbs(); stl_vertex diff = (facet.vertex[1] - facet.vertex[0]).cwiseAbs();
stl->stats.shortest_edge = std::max(diff(0), std::max(diff(1), diff(2))); stl->stats.shortest_edge = std::max(diff(0), std::max(diff(1), diff(2)));
first = false; first = false;
} }
// Now find the max and min values. // Now find the max and min values.
for (size_t i = 0; i < 3; ++ i) { for (size_t i = 0; i < 3; ++ i) {
stl->stats.min = stl->stats.min.cwiseMin(facet.vertex[i]); stl->stats.min = stl->stats.min.cwiseMin(facet.vertex[i]);
stl->stats.max = stl->stats.max.cwiseMax(facet.vertex[i]); stl->stats.max = stl->stats.max.cwiseMax(facet.vertex[i]);
} }
} }

View file

@ -25,13 +25,14 @@
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include <boost/log/trivial.hpp>
#include "stl.h" #include "stl.h"
static void stl_rotate(float *x, float *y, const double c, const double s); static void stl_rotate(float *x, float *y, const double c, const double s);
static float get_area(stl_facet *facet); static float get_area(stl_facet *facet);
static float get_volume(stl_file *stl); static float get_volume(stl_file *stl);
void stl_verify_neighbors(stl_file *stl) void stl_verify_neighbors(stl_file *stl)
{ {
stl->stats.backwards_edges = 0; stl->stats.backwards_edges = 0;
@ -56,7 +57,7 @@ void stl_verify_neighbors(stl_file *stl)
} }
if (edge_a.p1 != edge_b.p1 || edge_a.p2 != edge_b.p2) { if (edge_a.p1 != edge_b.p1 || edge_a.p2 != edge_b.p2) {
// These edges should match but they don't. Print results. // These edges should match but they don't. Print results.
printf("edge %d of facet %d doesn't match edge %d of facet %d\n", j, i, vnot + 1, neighbor); BOOST_LOG_TRIVIAL(info) << "edge " << j << " of facet " << i << " doesn't match edge " << (vnot + 1) << " of facet " << neighbor;
stl_write_facet(stl, (char*)"first facet", i); stl_write_facet(stl, (char*)"first facet", i);
stl_write_facet(stl, (char*)"second facet", neighbor); stl_write_facet(stl, (char*)"second facet", neighbor);
} }
@ -291,123 +292,104 @@ static float get_area(stl_facet *facet)
return 0.5f * n.dot(sum); return 0.5f * n.dot(sum);
} }
void stl_repair(stl_file *stl, void stl_repair(
int fixall_flag, stl_file *stl,
int exact_flag, bool fixall_flag,
int tolerance_flag, bool exact_flag,
float tolerance, bool tolerance_flag,
int increment_flag, float tolerance,
float increment, bool increment_flag,
int nearby_flag, float increment,
int iterations, bool nearby_flag,
int remove_unconnected_flag, int iterations,
int fill_holes_flag, bool remove_unconnected_flag,
int normal_directions_flag, bool fill_holes_flag,
int normal_values_flag, bool normal_directions_flag,
int reverse_all_flag, bool normal_values_flag,
int verbose_flag) { bool reverse_all_flag,
bool verbose_flag)
int i; {
int last_edges_fixed = 0; if (exact_flag || fixall_flag || nearby_flag || remove_unconnected_flag || fill_holes_flag || normal_directions_flag) {
if (verbose_flag)
printf("Checking exact...\n");
exact_flag = true;
stl_check_facets_exact(stl);
stl->stats.facets_w_1_bad_edge = (stl->stats.connected_facets_2_edge - stl->stats.connected_facets_3_edge);
stl->stats.facets_w_2_bad_edge = (stl->stats.connected_facets_1_edge - stl->stats.connected_facets_2_edge);
stl->stats.facets_w_3_bad_edge = (stl->stats.number_of_facets - stl->stats.connected_facets_1_edge);
}
if(exact_flag || fixall_flag || nearby_flag || remove_unconnected_flag if (nearby_flag || fixall_flag) {
|| fill_holes_flag || normal_directions_flag) { if (! tolerance_flag)
if (verbose_flag) tolerance = stl->stats.shortest_edge;
printf("Checking exact...\n"); if (! increment_flag)
exact_flag = 1; increment = stl->stats.bounding_diameter / 10000.0;
stl_check_facets_exact(stl);
stl->stats.facets_w_1_bad_edge =
(stl->stats.connected_facets_2_edge -
stl->stats.connected_facets_3_edge);
stl->stats.facets_w_2_bad_edge =
(stl->stats.connected_facets_1_edge -
stl->stats.connected_facets_2_edge);
stl->stats.facets_w_3_bad_edge =
(stl->stats.number_of_facets -
stl->stats.connected_facets_1_edge);
}
if(nearby_flag || fixall_flag) {
if(!tolerance_flag) {
tolerance = stl->stats.shortest_edge;
}
if(!increment_flag) {
increment = stl->stats.bounding_diameter / 10000.0;
} }
if(stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) { if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
for(i = 0; i < iterations; i++) { int last_edges_fixed = 0;
if(stl->stats.connected_facets_3_edge < for (int i = 0; i < iterations; ++ i) {
stl->stats.number_of_facets) { if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
if (verbose_flag) if (verbose_flag)
printf("\ printf("Checking nearby. Tolerance= %f Iteration=%d of %d...", tolerance, i + 1, iterations);
Checking nearby. Tolerance= %f Iteration=%d of %d...", stl_check_facets_nearby(stl, tolerance);
tolerance, i + 1, iterations); if (verbose_flag)
stl_check_facets_nearby(stl, tolerance); printf(" Fixed %d edges.\n", stl->stats.edges_fixed - last_edges_fixed);
if (verbose_flag) last_edges_fixed = stl->stats.edges_fixed;
printf(" Fixed %d edges.\n", tolerance += increment;
stl->stats.edges_fixed - last_edges_fixed); } else {
last_edges_fixed = stl->stats.edges_fixed; if (verbose_flag)
tolerance += increment; printf("All facets connected. No further nearby check necessary.\n");
} else { break;
if (verbose_flag) }
printf("\ }
All facets connected. No further nearby check necessary.\n"); } else if (verbose_flag)
break; printf("All facets connected. No nearby check necessary.\n");
}
}
} else {
if (verbose_flag)
printf("All facets connected. No nearby check necessary.\n");
}
}
if(remove_unconnected_flag || fixall_flag || fill_holes_flag) { if (remove_unconnected_flag || fixall_flag || fill_holes_flag) {
if(stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) { if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
if (verbose_flag) if (verbose_flag)
printf("Removing unconnected facets...\n"); printf("Removing unconnected facets...\n");
stl_remove_unconnected_facets(stl); stl_remove_unconnected_facets(stl);
} else } else if (verbose_flag)
if (verbose_flag) printf("No unconnected need to be removed.\n");
printf("No unconnected need to be removed.\n"); }
}
if(fill_holes_flag || fixall_flag) { if (fill_holes_flag || fixall_flag) {
if(stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) { if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
if (verbose_flag) if (verbose_flag)
printf("Filling holes...\n"); printf("Filling holes...\n");
stl_fill_holes(stl); stl_fill_holes(stl);
} else } else if (verbose_flag)
if (verbose_flag) printf("No holes need to be filled.\n");
printf("No holes need to be filled.\n"); }
}
if(reverse_all_flag) { if (reverse_all_flag) {
if (verbose_flag) if (verbose_flag)
printf("Reversing all facets...\n"); printf("Reversing all facets...\n");
stl_reverse_all_facets(stl); stl_reverse_all_facets(stl);
} }
if(normal_directions_flag || fixall_flag) { if (normal_directions_flag || fixall_flag) {
if (verbose_flag) if (verbose_flag)
printf("Checking normal directions...\n"); printf("Checking normal directions...\n");
stl_fix_normal_directions(stl); stl_fix_normal_directions(stl);
} }
if(normal_values_flag || fixall_flag) { if (normal_values_flag || fixall_flag) {
if (verbose_flag) if (verbose_flag)
printf("Checking normal values...\n"); printf("Checking normal values...\n");
stl_fix_normal_values(stl); stl_fix_normal_values(stl);
} }
/* Always calculate the volume. It shouldn't take too long */ // Always calculate the volume. It shouldn't take too long.
if (verbose_flag) if (verbose_flag)
printf("Calculating volume...\n"); printf("Calculating volume...\n");
stl_calculate_volume(stl); stl_calculate_volume(stl);
if(exact_flag) { if (exact_flag) {
if (verbose_flag) if (verbose_flag)
printf("Verifying neighbors...\n"); printf("Verifying neighbors...\n");
stl_verify_neighbors(stl); stl_verify_neighbors(stl);
} }
} }

View file

@ -837,7 +837,7 @@ void PresetBundle::load_config_file_config_bundle(const std::string &path, const
return preset_name_dst; return preset_name_dst;
// Try to generate another name. // Try to generate another name.
char buf[64]; char buf[64];
sprintf(buf, " (%d)", i); sprintf(buf, " (%d)", (int)i);
preset_name_dst = preset_name_src + buf + bundle_name; preset_name_dst = preset_name_src + buf + bundle_name;
} }
} }