mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 16:57:53 -06:00
admesh refactoring: replaced various diagnostics outputs with boost::log
This commit is contained in:
parent
6defabea53
commit
313ec7424a
7 changed files with 405 additions and 481 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,17 +108,9 @@ 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;
|
|
||||||
|
|
||||||
/* Open the file */
|
|
||||||
FILE *fp = boost::nowide::fopen(file, "w");
|
FILE *fp = boost::nowide::fopen(file, "w");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
error_msg = (char*)
|
BOOST_LOG_TRIVIAL(error) << "stl_write_ascii: Couldn't open " << file << " for writing";
|
||||||
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,29 +135,19 @@ bool stl_write_ascii(stl_file *stl, const char *file, const char *label)
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fp, "endsolid %s\n", label);
|
fprintf(fp, "endsolid %s\n", label);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return true;
|
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;
|
|
||||||
|
|
||||||
/* Open the file */
|
|
||||||
fp = boost::nowide::fopen(file, "w");
|
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
error_msg = (char*)
|
BOOST_LOG_TRIVIAL(error) << "stl_print_neighbors: Couldn't open " << file << " for writing";
|
||||||
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; i++) {
|
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||||
fprintf(fp, "%d, %d,%d, %d,%d, %d,%d\n",
|
fprintf(fp, "%d, %d,%d, %d,%d, %d,%d\n",
|
||||||
i,
|
i,
|
||||||
stl->neighbors_start[i].neighbor[0],
|
stl->neighbors_start[i].neighbor[0],
|
||||||
|
@ -191,23 +174,15 @@ void stl_internal_reverse_quads(char *buf, size_t cnt)
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* Open the file */
|
|
||||||
fp = boost::nowide::fopen(file, "wb");
|
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
error_msg = (char*)
|
BOOST_LOG_TRIVIAL(error) << "stl_write_binary: Couldn't open " << file << " for writing";
|
||||||
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fp, "%s", label);
|
fprintf(fp, "%s", label);
|
||||||
for(size_t i = strlen(label); i < LABEL_SIZE; i++) putc(0, fp);
|
for (size_t i = strlen(label); i < LABEL_SIZE; ++ i)
|
||||||
|
putc(0, fp);
|
||||||
|
|
||||||
fseek(fp, LABEL_SIZE, SEEK_SET);
|
fseek(fp, LABEL_SIZE, SEEK_SET);
|
||||||
#ifdef BOOST_LITTLE_ENDIAN
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
|
@ -260,39 +235,25 @@ 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;
|
|
||||||
char *error_msg;
|
|
||||||
stl_vertex connect_color = stl_vertex::Zero();
|
stl_vertex connect_color = stl_vertex::Zero();
|
||||||
stl_vertex uncon_1_color = stl_vertex::Zero();
|
stl_vertex uncon_1_color = stl_vertex::Zero();
|
||||||
stl_vertex uncon_2_color = stl_vertex::Zero();
|
stl_vertex uncon_2_color = stl_vertex::Zero();
|
||||||
stl_vertex uncon_3_color = stl_vertex::Zero();
|
stl_vertex uncon_3_color = stl_vertex::Zero();
|
||||||
stl_vertex color;
|
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) {
|
||||||
error_msg = (char*)
|
BOOST_LOG_TRIVIAL(error) << "stl_write_quad_object: Couldn't open " << file << " for writing";
|
||||||
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;
|
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;
|
|
||||||
} 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",
|
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),
|
||||||
|
@ -317,18 +278,9 @@ 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;
|
|
||||||
|
|
||||||
/* Open the file */
|
|
||||||
fp = boost::nowide::fopen(file, "w");
|
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
error_msg = (char*)
|
BOOST_LOG_TRIVIAL(error) << "stl_write_quad_object: Couldn't open " << file << " for writing";
|
||||||
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +309,6 @@ bool stl_write_dxf(stl_file *stl, const char *file, char *label)
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fp, "0\nENDSEC\n0\nEOF\n");
|
fprintf(fp, "0\nENDSEC\n0\nEOF\n");
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,39 +38,26 @@
|
||||||
|
|
||||||
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;
|
|
||||||
uint32_t num_facets;
|
|
||||||
int i;
|
|
||||||
size_t s;
|
|
||||||
unsigned char chtest[128];
|
|
||||||
int num_lines = 1;
|
|
||||||
char *error_msg;
|
|
||||||
|
|
||||||
/* Open the file in binary mode first */
|
|
||||||
FILE *fp = boost::nowide::fopen(file, "rb");
|
FILE *fp = boost::nowide::fopen(file, "rb");
|
||||||
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 */
|
|
||||||
sprintf(error_msg, "stl_initialize: Couldn't open %s for reading",
|
|
||||||
file);
|
|
||||||
perror(error_msg);
|
|
||||||
free(error_msg);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
/* Find size of file */
|
// Find size of file.
|
||||||
fseek(fp, 0, SEEK_END);
|
fseek(fp, 0, SEEK_END);
|
||||||
file_size = ftell(fp);
|
long file_size = ftell(fp);
|
||||||
|
|
||||||
/* Check for binary or ASCII file */
|
// Check for binary or ASCII file.
|
||||||
fseek(fp, HEADER_SIZE, SEEK_SET);
|
fseek(fp, HEADER_SIZE, SEEK_SET);
|
||||||
|
unsigned char chtest[128];
|
||||||
if (! fread(chtest, sizeof(chtest), 1, fp)) {
|
if (! fread(chtest, sizeof(chtest), 1, fp)) {
|
||||||
perror("The input is an empty file");
|
BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: The input is an empty file: " << file;
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
stl->stats.type = ascii;
|
stl->stats.type = ascii;
|
||||||
for(s = 0; s < sizeof(chtest); s++) {
|
for (size_t s = 0; s < sizeof(chtest); s++) {
|
||||||
if (chtest[s] > 127) {
|
if (chtest[s] > 127) {
|
||||||
stl->stats.type = binary;
|
stl->stats.type = binary;
|
||||||
break;
|
break;
|
||||||
|
@ -77,75 +65,72 @@ static FILE* stl_open_count_facets(stl_file *stl, const char *file)
|
||||||
}
|
}
|
||||||
rewind(fp);
|
rewind(fp);
|
||||||
|
|
||||||
/* Get the header and the number of facets in the .STL file */
|
uint32_t num_facets = 0;
|
||||||
/* If the .STL file is binary, then do the following */
|
|
||||||
|
// Get the header and the number of facets in the .STL file.
|
||||||
|
// 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.
|
||||||
|
uint32_t header_num_facets;
|
||||||
bool header_num_faces_read = fread(&header_num_facets, sizeof(uint32_t), 1, fp) != 0;
|
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:
|
||||||
/* Otherwise, if the .STL file is ASCII, then do the following */
|
else
|
||||||
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 */
|
|
||||||
sprintf(error_msg, "stl_initialize: Couldn't open %s for reading",
|
|
||||||
file);
|
|
||||||
perror(error_msg);
|
|
||||||
free(error_msg);
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the number of facets */
|
// Find the number of facets.
|
||||||
char linebuf[100];
|
char linebuf[100];
|
||||||
|
int num_lines = 1;
|
||||||
while (fgets(linebuf, 100, fp) != nullptr) {
|
while (fgets(linebuf, 100, fp) != nullptr) {
|
||||||
/* don't count short lines */
|
// Don't count short lines.
|
||||||
if (strlen(linebuf) <= 4) continue;
|
if (strlen(linebuf) <= 4)
|
||||||
|
continue;
|
||||||
/* skip solid/endsolid lines as broken STL file generators may put several of them */
|
// 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) continue;
|
if (strncmp(linebuf, "solid", 5) == 0 || strncmp(linebuf, "endsolid", 8) == 0)
|
||||||
|
continue;
|
||||||
++ num_lines;
|
++ num_lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
rewind(fp);
|
rewind(fp);
|
||||||
|
|
||||||
/* Get the header */
|
// Get the header.
|
||||||
for(i = 0;
|
int i = 0;
|
||||||
(i < 80) && (stl->stats.header[i] = getc(fp)) != '\n'; i++);
|
for (; i < 80 && (stl->stats.header[i] = getc(fp)) != '\n'; ++ i) ;
|
||||||
stl->stats.header[i] = '\0'; /* Lose the '\n' */
|
stl->stats.header[i] = '\0'; // Lose the '\n'
|
||||||
stl->stats.header[80] = '\0';
|
stl->stats.header[80] = '\0';
|
||||||
|
|
||||||
num_facets = num_lines / ASCII_LINES_PER_FACET;
|
num_facets = num_lines / ASCII_LINES_PER_FACET;
|
||||||
}
|
}
|
||||||
|
|
||||||
stl->stats.number_of_facets += num_facets;
|
stl->stats.number_of_facets += num_facets;
|
||||||
stl->stats.original_num_facets = stl->stats.number_of_facets;
|
stl->stats.original_num_facets = stl->stats.number_of_facets;
|
||||||
return fp;
|
return fp;
|
||||||
|
@ -156,29 +141,25 @@ 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)
|
||||||
{
|
{
|
||||||
|
if (stl->stats.type == binary)
|
||||||
|
fseek(fp, HEADER_SIZE, SEEK_SET);
|
||||||
|
else
|
||||||
|
rewind(fp);
|
||||||
|
|
||||||
|
char normal_buf[3][32];
|
||||||
|
for (uint32_t i = first_facet; i < stl->stats.number_of_facets; ++i) {
|
||||||
stl_facet facet;
|
stl_facet facet;
|
||||||
|
|
||||||
if (stl->stats.type == binary) {
|
if (stl->stats.type == binary) {
|
||||||
fseek(fp, HEADER_SIZE, SEEK_SET);
|
// Read a single facet from a binary .STL file. We assume little-endian architecture!
|
||||||
} else {
|
|
||||||
rewind(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
char normal_buf[3][32];
|
|
||||||
for(uint32_t i = first_facet; i < stl->stats.number_of_facets; i++) {
|
|
||||||
if(stl->stats.type == binary)
|
|
||||||
/* Read a single facet from a binary .STL file */
|
|
||||||
{
|
|
||||||
/* we assume little-endian architecture! */
|
|
||||||
if (fread(&facet, 1, SIZEOF_STL_FACET, fp) != SIZEOF_STL_FACET)
|
if (fread(&facet, 1, SIZEOF_STL_FACET, fp) != SIZEOF_STL_FACET)
|
||||||
return false;
|
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");
|
||||||
|
@ -199,7 +180,7 @@ static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first)
|
||||||
// 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) {
|
||||||
perror("Something is syntactically very wrong with this ASCII STL!");
|
BOOST_LOG_TRIVIAL(error) << "Something is syntactically very wrong with this ASCII STL! ";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,10 +209,11 @@ static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first)
|
||||||
}
|
}
|
||||||
#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.size = stl->stats.max - stl->stats.min;
|
||||||
stl->stats.bounding_diameter = stl->stats.size.norm();
|
stl->stats.bounding_diameter = stl->stats.size.norm();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -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,84 +292,66 @@ 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,
|
||||||
|
bool tolerance_flag,
|
||||||
float tolerance,
|
float tolerance,
|
||||||
int increment_flag,
|
bool increment_flag,
|
||||||
float increment,
|
float increment,
|
||||||
int nearby_flag,
|
bool nearby_flag,
|
||||||
int iterations,
|
int iterations,
|
||||||
int remove_unconnected_flag,
|
bool remove_unconnected_flag,
|
||||||
int fill_holes_flag,
|
bool fill_holes_flag,
|
||||||
int normal_directions_flag,
|
bool normal_directions_flag,
|
||||||
int normal_values_flag,
|
bool normal_values_flag,
|
||||||
int reverse_all_flag,
|
bool reverse_all_flag,
|
||||||
int verbose_flag) {
|
bool verbose_flag)
|
||||||
|
{
|
||||||
int i;
|
if (exact_flag || fixall_flag || nearby_flag || remove_unconnected_flag || fill_holes_flag || normal_directions_flag) {
|
||||||
int last_edges_fixed = 0;
|
|
||||||
|
|
||||||
if(exact_flag || fixall_flag || nearby_flag || remove_unconnected_flag
|
|
||||||
|| fill_holes_flag || normal_directions_flag) {
|
|
||||||
if (verbose_flag)
|
if (verbose_flag)
|
||||||
printf("Checking exact...\n");
|
printf("Checking exact...\n");
|
||||||
exact_flag = 1;
|
exact_flag = true;
|
||||||
stl_check_facets_exact(stl);
|
stl_check_facets_exact(stl);
|
||||||
stl->stats.facets_w_1_bad_edge =
|
stl->stats.facets_w_1_bad_edge = (stl->stats.connected_facets_2_edge - stl->stats.connected_facets_3_edge);
|
||||||
(stl->stats.connected_facets_2_edge -
|
stl->stats.facets_w_2_bad_edge = (stl->stats.connected_facets_1_edge - stl->stats.connected_facets_2_edge);
|
||||||
stl->stats.connected_facets_3_edge);
|
stl->stats.facets_w_3_bad_edge = (stl->stats.number_of_facets - stl->stats.connected_facets_1_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 (nearby_flag || fixall_flag) {
|
||||||
if(!tolerance_flag) {
|
if (! tolerance_flag)
|
||||||
tolerance = stl->stats.shortest_edge;
|
tolerance = stl->stats.shortest_edge;
|
||||||
}
|
if (! increment_flag)
|
||||||
if(!increment_flag) {
|
|
||||||
increment = stl->stats.bounding_diameter / 10000.0;
|
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...",
|
|
||||||
tolerance, i + 1, iterations);
|
|
||||||
stl_check_facets_nearby(stl, tolerance);
|
stl_check_facets_nearby(stl, tolerance);
|
||||||
if (verbose_flag)
|
if (verbose_flag)
|
||||||
printf(" Fixed %d edges.\n",
|
printf(" Fixed %d edges.\n", stl->stats.edges_fixed - last_edges_fixed);
|
||||||
stl->stats.edges_fixed - last_edges_fixed);
|
|
||||||
last_edges_fixed = stl->stats.edges_fixed;
|
last_edges_fixed = stl->stats.edges_fixed;
|
||||||
tolerance += increment;
|
tolerance += increment;
|
||||||
} else {
|
} else {
|
||||||
if (verbose_flag)
|
if (verbose_flag)
|
||||||
printf("\
|
printf("All facets connected. No further nearby check necessary.\n");
|
||||||
All facets connected. No further nearby check necessary.\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if (verbose_flag)
|
||||||
if (verbose_flag)
|
|
||||||
printf("All facets connected. No nearby check necessary.\n");
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,8 +360,7 @@ All facets connected. No further nearby check necessary.\n");
|
||||||
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +382,7 @@ All facets connected. No further nearby check necessary.\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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue