admesh refactoring: Using boost::object_pool for linked list memory

allocation.
This commit is contained in:
bubnikv 2019-06-11 09:29:32 +02:00
parent 590c290ede
commit 5fc465b7e8
3 changed files with 284 additions and 266 deletions

View file

@ -28,8 +28,9 @@
#include <algorithm>
#include <vector>
#include <boost/predef/other/endian.h>
#include <boost/log/trivial.hpp>
#include <boost/detail/endian.hpp>
#include <boost/pool/object_pool.hpp>
#include "stl.h"
@ -42,11 +43,11 @@ struct HashEdge {
int hash(int M) const { return ((key[0] / 11 + key[1] / 7 + key[2] / 3) ^ (key[3] / 11 + key[4] / 7 + key[5] / 3)) % M; }
// Index of a facet owning this edge.
int facet_number;
int facet_number;
// Index of this edge inside the facet with an index of facet_number.
// If this edge is stored backwards, which_edge is increased by 3.
int which_edge;
struct HashEdge *next;
int which_edge;
HashEdge *next;
void load_exact(stl_file *stl, const stl_vertex *a, const stl_vertex *b)
{
@ -69,15 +70,15 @@ struct HashEdge {
// Switch negative zeros to positive zeros, so memcmp will consider them to be equal.
for (size_t i = 0; i < 6; ++ i) {
unsigned char *p = (unsigned char*)(this->key + i);
#ifdef BOOST_LITTLE_ENDIAN
#if BOOST_ENDIAN_LITTLE_BYTE
if (p[0] == 0 && p[1] == 0 && p[2] == 0 && p[3] == 0x80)
// Negative zero, switch to positive zero.
p[3] = 0;
#else /* BOOST_LITTLE_ENDIAN */
#else /* BOOST_ENDIAN_LITTLE_BYTE */
if (p[0] == 0x80 && p[1] == 0 && p[2] == 0 && p[3] == 0)
// Negative zero, switch to positive zero.
p[0] = 0;
#endif /* BOOST_LITTLE_ENDIAN */
#endif /* BOOST_ENDIAN_LITTLE_BYTE */
}
}
@ -115,7 +116,7 @@ struct HashTableEdges {
HashTableEdges(size_t number_of_faces) {
this->M = (int)hash_size_from_nr_faces(number_of_faces);
this->heads.assign(this->M, nullptr);
this->tail = new HashEdge;
this->tail = pool.construct();
this->tail->next = this->tail;
for (int i = 0; i < this->M; ++ i)
this->heads[i] = this->tail;
@ -124,80 +125,32 @@ struct HashTableEdges {
for (int i = 0; i < this->M; ++ i) {
for (HashEdge *temp = this->heads[i]; this->heads[i] != this->tail; temp = this->heads[i]) {
this->heads[i] = this->heads[i]->next;
delete temp;
pool.destroy(temp);
#ifndef NDEBUG
++ this->freed;
#endif /* NDEBUG */
}
}
this->heads.clear();
delete this->tail;
pool.destroy(this->tail);
this->tail = nullptr;
}
void insert_edge(stl_file *stl, const HashEdge &edge, void (*match_neighbors)(stl_file *stl, const HashEdge &edge_a, const HashEdge &edge_b))
void insert_edge_exact(stl_file *stl, const HashEdge &edge)
{
int chain_number = edge.hash(this->M);
HashEdge *link = this->heads[chain_number];
if (link == this->tail) {
// This list doesn't have any edges currently in it. Add this one.
HashEdge *new_edge = new HashEdge(edge);
#ifndef NDEBUG
++ this->malloced;
#endif /* NDEBUG */
new_edge->next = this->tail;
this->heads[chain_number] = new_edge;
} else if (edges_equal(edge, *link)) {
// This is a match. Record result in neighbors list.
match_neighbors(stl, edge, *link);
// Delete the matched edge from the list.
this->heads[chain_number] = link->next;
delete link;
#ifndef NDEBUG
++ this->freed;
#endif /* NDEBUG */
} else {
// Continue through the rest of the list.
for (;;) {
if (link->next == this->tail) {
// This is the last item in the list. Insert a new edge.
HashEdge *new_edge = new HashEdge;
#ifndef NDEBUG
++ this->malloced;
#endif /* NDEBUG */
*new_edge = edge;
new_edge->next = this->tail;
link->next = new_edge;
#ifndef NDEBUG
++ this->collisions;
#endif /* NDEBUG */
break;
}
if (edges_equal(edge, *link->next)) {
// This is a match. Record result in neighbors list.
match_neighbors(stl, edge, *link->next);
// Delete the matched edge from the list.
HashEdge *temp = link->next;
link->next = link->next->next;
delete temp;
#ifndef NDEBUG
++ this->freed;
#endif /* NDEBUG */
break;
}
// This is not a match. Go to the next link.
link = link->next;
#ifndef NDEBUG
++ this->collisions;
#endif /* NDEBUG */
}
}
this->insert_edge(stl, edge, [stl](const HashEdge& edge1, const HashEdge& edge2) { record_neighbors(stl, edge1, edge2); });
}
void insert_edge_nearby(stl_file *stl, const HashEdge &edge)
{
this->insert_edge(stl, edge, [stl](const HashEdge& edge1, const HashEdge& edge2) { match_neighbors_nearby(stl, edge1, edge2); });
}
// Hash table on edges
std::vector<HashEdge*> heads;
HashEdge* tail;
int M;
boost::object_pool<HashEdge> pool;
#ifndef NDEBUG
size_t malloced = 0;
@ -216,198 +169,260 @@ private:
return (it == primes.end()) ? primes.back() : *it;
}
// MatchNeighbors(stl_file *stl, const HashEdge &edge_a, const HashEdge &edge_b)
template<typename MatchNeighbors>
void insert_edge(stl_file *stl, const HashEdge &edge, MatchNeighbors match_neighbors)
{
int chain_number = edge.hash(this->M);
HashEdge *link = this->heads[chain_number];
if (link == this->tail) {
// This list doesn't have any edges currently in it. Add this one.
HashEdge *new_edge = pool.construct(edge);
#ifndef NDEBUG
++ this->malloced;
#endif /* NDEBUG */
new_edge->next = this->tail;
this->heads[chain_number] = new_edge;
} else if (edges_equal(edge, *link)) {
// This is a match. Record result in neighbors list.
match_neighbors(edge, *link);
// Delete the matched edge from the list.
this->heads[chain_number] = link->next;
pool.destroy(link);
#ifndef NDEBUG
++ this->freed;
#endif /* NDEBUG */
} else {
// Continue through the rest of the list.
for (;;) {
if (link->next == this->tail) {
// This is the last item in the list. Insert a new edge.
HashEdge *new_edge = pool.construct();
#ifndef NDEBUG
++ this->malloced;
#endif /* NDEBUG */
*new_edge = edge;
new_edge->next = this->tail;
link->next = new_edge;
#ifndef NDEBUG
++ this->collisions;
#endif /* NDEBUG */
break;
}
if (edges_equal(edge, *link->next)) {
// This is a match. Record result in neighbors list.
match_neighbors(edge, *link->next);
// Delete the matched edge from the list.
HashEdge *temp = link->next;
link->next = link->next->next;
pool.destroy(temp);
#ifndef NDEBUG
++ this->freed;
#endif /* NDEBUG */
break;
}
// This is not a match. Go to the next link.
link = link->next;
#ifndef NDEBUG
++ this->collisions;
#endif /* NDEBUG */
}
}
}
// Edges equal for hashing. Edgesof different facet are allowed to be matched.
static inline bool edges_equal(const HashEdge &edge_a, const HashEdge &edge_b)
{
return edge_a.facet_number != edge_b.facet_number && edge_a == edge_b;
}
static void record_neighbors(stl_file *stl, const HashEdge &edge_a, const HashEdge &edge_b)
{
// Facet a's neighbor is facet b
stl->neighbors_start[edge_a.facet_number].neighbor[edge_a.which_edge % 3] = edge_b.facet_number; /* sets the .neighbor part */
stl->neighbors_start[edge_a.facet_number].which_vertex_not[edge_a.which_edge % 3] = (edge_b.which_edge + 2) % 3; /* sets the .which_vertex_not part */
// Facet b's neighbor is facet a
stl->neighbors_start[edge_b.facet_number].neighbor[edge_b.which_edge % 3] = edge_a.facet_number; /* sets the .neighbor part */
stl->neighbors_start[edge_b.facet_number].which_vertex_not[edge_b.which_edge % 3] = (edge_a.which_edge + 2) % 3; /* sets the .which_vertex_not part */
if (((edge_a.which_edge < 3) && (edge_b.which_edge < 3)) || ((edge_a.which_edge > 2) && (edge_b.which_edge > 2))) {
// These facets are oriented in opposite directions, their normals are probably messed up.
stl->neighbors_start[edge_a.facet_number].which_vertex_not[edge_a.which_edge % 3] += 3;
stl->neighbors_start[edge_b.facet_number].which_vertex_not[edge_b.which_edge % 3] += 3;
}
// Count successful connects:
// Total connects:
stl->stats.connected_edges += 2;
// Count individual connects:
switch (stl->neighbors_start[edge_a.facet_number].num_neighbors()) {
case 1: ++ stl->stats.connected_facets_1_edge; break;
case 2: ++ stl->stats.connected_facets_2_edge; break;
case 3: ++ stl->stats.connected_facets_3_edge; break;
default: assert(false);
}
switch (stl->neighbors_start[edge_b.facet_number].num_neighbors()) {
case 1: ++ stl->stats.connected_facets_1_edge; break;
case 2: ++ stl->stats.connected_facets_2_edge; break;
case 3: ++ stl->stats.connected_facets_3_edge; break;
default: assert(false);
}
}
static void match_neighbors_nearby(stl_file *stl, const HashEdge &edge_a, const HashEdge &edge_b)
{
record_neighbors(stl, edge_a, edge_b);
// Which vertices to change
int facet1 = -1;
int facet2 = -1;
int vertex1, vertex2;
stl_vertex new_vertex1, new_vertex2;
{
int v1a; // pair 1, facet a
int v1b; // pair 1, facet b
int v2a; // pair 2, facet a
int v2b; // pair 2, facet b
// Find first pair.
if (edge_a.which_edge < 3) {
v1a = edge_a.which_edge;
v2a = (edge_a.which_edge + 1) % 3;
} else {
v2a = edge_a.which_edge % 3;
v1a = (edge_a.which_edge + 1) % 3;
}
if (edge_b.which_edge < 3) {
v1b = edge_b.which_edge;
v2b = (edge_b.which_edge + 1) % 3;
} else {
v2b = edge_b.which_edge % 3;
v1b = (edge_b.which_edge + 1) % 3;
}
// Of the first pair, which vertex, if any, should be changed
if (stl->facet_start[edge_a.facet_number].vertex[v1a] != stl->facet_start[edge_b.facet_number].vertex[v1b]) {
// These facets are different.
if ( (stl->neighbors_start[edge_a.facet_number].neighbor[v1a] == -1)
&& (stl->neighbors_start[edge_a.facet_number].neighbor[(v1a + 2) % 3] == -1)) {
// This vertex has no neighbors. This is a good one to change.
facet1 = edge_a.facet_number;
vertex1 = v1a;
new_vertex1 = stl->facet_start[edge_b.facet_number].vertex[v1b];
} else {
facet1 = edge_b.facet_number;
vertex1 = v1b;
new_vertex1 = stl->facet_start[edge_a.facet_number].vertex[v1a];
}
}
// Of the second pair, which vertex, if any, should be changed.
if (stl->facet_start[edge_a.facet_number].vertex[v2a] == stl->facet_start[edge_b.facet_number].vertex[v2b]) {
// These facets are different.
if ( (stl->neighbors_start[edge_a.facet_number].neighbor[v2a] == -1)
&& (stl->neighbors_start[edge_a.facet_number].neighbor[(v2a + 2) % 3] == -1)) {
// This vertex has no neighbors. This is a good one to change.
facet2 = edge_a.facet_number;
vertex2 = v2a;
new_vertex2 = stl->facet_start[edge_b.facet_number].vertex[v2b];
} else {
facet2 = edge_b.facet_number;
vertex2 = v2b;
new_vertex2 = stl->facet_start[edge_a.facet_number].vertex[v2a];
}
}
}
auto change_vertices = [stl](int facet_num, int vnot, stl_vertex new_vertex)
{
int first_facet = facet_num;
bool direction = false;
for (;;) {
int pivot_vertex;
int next_edge;
if (vnot > 2) {
if (direction) {
pivot_vertex = (vnot + 1) % 3;
next_edge = vnot % 3;
}
else {
pivot_vertex = (vnot + 2) % 3;
next_edge = pivot_vertex;
}
direction = !direction;
}
else {
if (direction) {
pivot_vertex = (vnot + 2) % 3;
next_edge = pivot_vertex;
}
else {
pivot_vertex = (vnot + 1) % 3;
next_edge = vnot;
}
}
#if 0
if (stl->facet_start[facet_num].vertex[pivot_vertex](0) == new_vertex(0) &&
stl->facet_start[facet_num].vertex[pivot_vertex](1) == new_vertex(1) &&
stl->facet_start[facet_num].vertex[pivot_vertex](2) == new_vertex(2))
printf("Changing vertex %f,%f,%f: Same !!!\r\n", new_vertex(0), new_vertex(1), new_vertex(2));
else {
if (stl->facet_start[facet_num].vertex[pivot_vertex](0) != new_vertex(0))
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
stl->facet_start[facet_num].vertex[pivot_vertex](0),
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex](0)),
new_vertex(0),
*reinterpret_cast<const int*>(&new_vertex(0)));
if (stl->facet_start[facet_num].vertex[pivot_vertex](1) != new_vertex(1))
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
stl->facet_start[facet_num].vertex[pivot_vertex](1),
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex](1)),
new_vertex(1),
*reinterpret_cast<const int*>(&new_vertex(1)));
if (stl->facet_start[facet_num].vertex[pivot_vertex](2) != new_vertex(2))
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
stl->facet_start[facet_num].vertex[pivot_vertex](2),
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex](2)),
new_vertex(2),
*reinterpret_cast<const int*>(&new_vertex(2)));
}
#endif
stl->facet_start[facet_num].vertex[pivot_vertex] = new_vertex;
vnot = stl->neighbors_start[facet_num].which_vertex_not[next_edge];
facet_num = stl->neighbors_start[facet_num].neighbor[next_edge];
if (facet_num == -1)
break;
if (facet_num == first_facet) {
// back to the beginning
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;
}
}
};
if (facet1 != -1) {
int vnot1 = (facet1 == edge_a.facet_number) ?
(edge_a.which_edge + 2) % 3 :
(edge_b.which_edge + 2) % 3;
if (((vnot1 + 2) % 3) == vertex1)
vnot1 += 3;
change_vertices(facet1, vnot1, new_vertex1);
}
if (facet2 != -1) {
int vnot2 = (facet2 == edge_a.facet_number) ?
(edge_a.which_edge + 2) % 3 :
(edge_b.which_edge + 2) % 3;
if (((vnot2 + 2) % 3) == vertex2)
vnot2 += 3;
change_vertices(facet2, vnot2, new_vertex2);
}
stl->stats.edges_fixed += 2;
}
};
static void record_neighbors(stl_file *stl, const HashEdge &edge_a, const HashEdge &edge_b)
{
// Facet a's neighbor is facet b
stl->neighbors_start[edge_a.facet_number].neighbor[edge_a.which_edge % 3] = edge_b.facet_number; /* sets the .neighbor part */
stl->neighbors_start[edge_a.facet_number].which_vertex_not[edge_a.which_edge % 3] = (edge_b.which_edge + 2) % 3; /* sets the .which_vertex_not part */
// Facet b's neighbor is facet a
stl->neighbors_start[edge_b.facet_number].neighbor[edge_b.which_edge % 3] = edge_a.facet_number; /* sets the .neighbor part */
stl->neighbors_start[edge_b.facet_number].which_vertex_not[edge_b.which_edge % 3] = (edge_a.which_edge + 2) % 3; /* sets the .which_vertex_not part */
if (((edge_a.which_edge < 3) && (edge_b.which_edge < 3)) || ((edge_a.which_edge > 2) && (edge_b.which_edge > 2))) {
// These facets are oriented in opposite directions, their normals are probably messed up.
stl->neighbors_start[edge_a.facet_number].which_vertex_not[edge_a.which_edge % 3] += 3;
stl->neighbors_start[edge_b.facet_number].which_vertex_not[edge_b.which_edge % 3] += 3;
}
// Count successful connects:
// Total connects:
stl->stats.connected_edges += 2;
// Count individual connects:
switch (stl->neighbors_start[edge_a.facet_number].num_neighbors()) {
case 1: ++ stl->stats.connected_facets_1_edge; break;
case 2: ++ stl->stats.connected_facets_2_edge; break;
case 3: ++ stl->stats.connected_facets_3_edge; break;
default: assert(false);
}
switch (stl->neighbors_start[edge_b.facet_number].num_neighbors()) {
case 1: ++ stl->stats.connected_facets_1_edge; break;
case 2: ++ stl->stats.connected_facets_2_edge; break;
case 3: ++ stl->stats.connected_facets_3_edge; break;
default: assert(false);
}
}
static void match_neighbors_nearby(stl_file *stl, const HashEdge &edge_a, const HashEdge &edge_b)
{
record_neighbors(stl, edge_a, edge_b);
// Which vertices to change
int facet1 = -1;
int facet2 = -1;
int vertex1, vertex2;
stl_vertex new_vertex1, new_vertex2;
{
int v1a; // pair 1, facet a
int v1b; // pair 1, facet b
int v2a; // pair 2, facet a
int v2b; // pair 2, facet b
// Find first pair.
if (edge_a.which_edge < 3) {
v1a = edge_a.which_edge;
v2a = (edge_a.which_edge + 1) % 3;
} else {
v2a = edge_a.which_edge % 3;
v1a = (edge_a.which_edge + 1) % 3;
}
if (edge_b.which_edge < 3) {
v1b = edge_b.which_edge;
v2b = (edge_b.which_edge + 1) % 3;
} else {
v2b = edge_b.which_edge % 3;
v1b = (edge_b.which_edge + 1) % 3;
}
// Of the first pair, which vertex, if any, should be changed
if (stl->facet_start[edge_a.facet_number].vertex[v1a] != stl->facet_start[edge_b.facet_number].vertex[v1b]) {
// These facets are different.
if ( (stl->neighbors_start[edge_a.facet_number].neighbor[v1a] == -1)
&& (stl->neighbors_start[edge_a.facet_number].neighbor[(v1a + 2) % 3] == -1)) {
// This vertex has no neighbors. This is a good one to change.
facet1 = edge_a.facet_number;
vertex1 = v1a;
new_vertex1 = stl->facet_start[edge_b.facet_number].vertex[v1b];
} else {
facet1 = edge_b.facet_number;
vertex1 = v1b;
new_vertex1 = stl->facet_start[edge_a.facet_number].vertex[v1a];
}
}
// Of the second pair, which vertex, if any, should be changed.
if (stl->facet_start[edge_a.facet_number].vertex[v2a] == stl->facet_start[edge_b.facet_number].vertex[v2b]) {
// These facets are different.
if ( (stl->neighbors_start[edge_a.facet_number].neighbor[v2a] == -1)
&& (stl->neighbors_start[edge_a.facet_number].neighbor[(v2a + 2) % 3] == -1)) {
// This vertex has no neighbors. This is a good one to change.
facet2 = edge_a.facet_number;
vertex2 = v2a;
new_vertex2 = stl->facet_start[edge_b.facet_number].vertex[v2b];
} else {
facet2 = edge_b.facet_number;
vertex2 = v2b;
new_vertex2 = stl->facet_start[edge_a.facet_number].vertex[v2a];
}
}
}
auto change_vertices = [stl](int facet_num, int vnot, stl_vertex new_vertex)
{
int first_facet = facet_num;
bool direction = false;
for (;;) {
int pivot_vertex;
int next_edge;
if (vnot > 2) {
if (direction) {
pivot_vertex = (vnot + 1) % 3;
next_edge = vnot % 3;
}
else {
pivot_vertex = (vnot + 2) % 3;
next_edge = pivot_vertex;
}
direction = !direction;
}
else {
if (direction) {
pivot_vertex = (vnot + 2) % 3;
next_edge = pivot_vertex;
}
else {
pivot_vertex = (vnot + 1) % 3;
next_edge = vnot;
}
}
#if 0
if (stl->facet_start[facet_num].vertex[pivot_vertex](0) == new_vertex(0) &&
stl->facet_start[facet_num].vertex[pivot_vertex](1) == new_vertex(1) &&
stl->facet_start[facet_num].vertex[pivot_vertex](2) == new_vertex(2))
printf("Changing vertex %f,%f,%f: Same !!!\r\n", new_vertex(0), new_vertex(1), new_vertex(2));
else {
if (stl->facet_start[facet_num].vertex[pivot_vertex](0) != new_vertex(0))
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
stl->facet_start[facet_num].vertex[pivot_vertex](0),
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex](0)),
new_vertex(0),
*reinterpret_cast<const int*>(&new_vertex(0)));
if (stl->facet_start[facet_num].vertex[pivot_vertex](1) != new_vertex(1))
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
stl->facet_start[facet_num].vertex[pivot_vertex](1),
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex](1)),
new_vertex(1),
*reinterpret_cast<const int*>(&new_vertex(1)));
if (stl->facet_start[facet_num].vertex[pivot_vertex](2) != new_vertex(2))
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
stl->facet_start[facet_num].vertex[pivot_vertex](2),
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex](2)),
new_vertex(2),
*reinterpret_cast<const int*>(&new_vertex(2)));
}
#endif
stl->facet_start[facet_num].vertex[pivot_vertex] = new_vertex;
vnot = stl->neighbors_start[facet_num].which_vertex_not[next_edge];
facet_num = stl->neighbors_start[facet_num].neighbor[next_edge];
if (facet_num == -1)
break;
if (facet_num == first_facet) {
// back to the beginning
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;
}
}
};
if (facet1 != -1) {
int vnot1 = (facet1 == edge_a.facet_number) ?
(edge_a.which_edge + 2) % 3 :
(edge_b.which_edge + 2) % 3;
if (((vnot1 + 2) % 3) == vertex1)
vnot1 += 3;
change_vertices(facet1, vnot1, new_vertex1);
}
if (facet2 != -1) {
int vnot2 = (facet2 == edge_a.facet_number) ?
(edge_a.which_edge + 2) % 3 :
(edge_b.which_edge + 2) % 3;
if (((vnot2 + 2) % 3) == vertex2)
vnot2 += 3;
change_vertices(facet2, vnot2, new_vertex2);
}
stl->stats.edges_fixed += 2;
}
// This function builds the neighbors list. No modifications are made
// to any of the facets. The edges are said to match only if all six
// floats of the first edge matches all six floats of the second edge.
@ -445,7 +460,7 @@ void stl_check_facets_exact(stl_file *stl)
edge.facet_number = i;
edge.which_edge = j;
edge.load_exact(stl, &facet.vertex[j], &facet.vertex[(j + 1) % 3]);
hash_table.insert_edge(stl, edge, record_neighbors);
hash_table.insert_edge_exact(stl, edge);
}
}
@ -476,7 +491,7 @@ void stl_check_facets_nearby(stl_file *stl, float tolerance)
edge.which_edge = j;
if (edge.load_nearby(stl, facet.vertex[j], facet.vertex[(j + 1) % 3], tolerance))
// Only insert edges that have different keys.
hash_table.insert_edge(stl, edge, match_neighbors_nearby);
hash_table.insert_edge_nearby(stl, edge);
}
}
}
@ -654,7 +669,7 @@ void stl_fill_holes(stl_file *stl)
edge.facet_number = i;
edge.which_edge = j;
edge.load_exact(stl, &facet.vertex[j], &facet.vertex[(j + 1) % 3]);
hash_table.insert_edge(stl, edge, record_neighbors);
hash_table.insert_edge_exact(stl, edge);
}
}
@ -704,7 +719,7 @@ void stl_fill_holes(stl_file *stl)
edge.facet_number = stl->stats.number_of_facets - 1;
edge.which_edge = k;
edge.load_exact(stl, &new_facet.vertex[k], &new_facet.vertex[(k + 1) % 3]);
hash_table.insert_edge(stl, edge, record_neighbors);
hash_table.insert_edge_exact(stl, edge);
}
break;
}

View file

@ -25,6 +25,8 @@
#include <string.h>
#include <math.h>
#include <boost/pool/object_pool.hpp>
#include "stl.h"
static void reverse_facet(stl_file *stl, int facet_num)
@ -120,8 +122,9 @@ void stl_fix_normal_directions(stl_file *stl)
};
// Initialize linked list.
stl_normal *head = new stl_normal;
stl_normal *tail = new stl_normal;
boost::object_pool<stl_normal> pool;
stl_normal *head = pool.construct();
stl_normal *tail = pool.construct();
head->next = tail;
tail->next = tail;
@ -168,7 +171,7 @@ void stl_fix_normal_directions(stl_file *stl)
// If we haven't fixed this facet yet, add it to the list:
if (norm_sw[stl->neighbors_start[facet_num].neighbor[j]] != 1) {
// Add node to beginning of list.
stl_normal *newn = new stl_normal;
stl_normal *newn = pool.construct();
newn->facet_num = stl->neighbors_start[facet_num].neighbor[j];
newn->next = head->next;
head->next = newn;
@ -189,7 +192,7 @@ void stl_fix_normal_directions(stl_file *stl)
}
stl_normal *temp = head->next; // Delete this facet from the list.
head->next = head->next->next;
delete temp;
pool.destroy(temp);
} else { // If we ran out of facets to fix: All of the facets in this part have been fixed.
++ stl->stats.number_of_parts;
if (checked >= stl->stats.number_of_facets)
@ -211,8 +214,8 @@ void stl_fix_normal_directions(stl_file *stl)
}
}
delete head;
delete tail;
pool.destroy(head);
pool.destroy(tail);
}
void stl_fix_normal_values(stl_file *stl)

View file

@ -25,7 +25,7 @@
#include <boost/log/trivial.hpp>
#include <boost/nowide/cstdio.hpp>
#include <boost/detail/endian.hpp>
#include <boost/predef/other/endian.h>
#include "stl.h"
@ -114,7 +114,7 @@ bool stl_print_neighbors(stl_file *stl, char *file)
return true;
}
#ifndef BOOST_LITTLE_ENDIAN
#if BOOST_ENDIAN_BIG_BYTE
// 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)
{
@ -141,11 +141,11 @@ bool stl_write_binary(stl_file *stl, const char *file, const char *label)
#define SEEK_SET 0
#endif
fseek(fp, LABEL_SIZE, SEEK_SET);
#ifdef BOOST_LITTLE_ENDIAN
#if BOOST_ENDIAN_LITTLE_BYTE
fwrite(&stl->stats.number_of_facets, 4, 1, fp);
for (const stl_facet &facet : stl->facet_start)
fwrite(&facet, SIZEOF_STL_FACET, 1, fp);
#else /* BOOST_LITTLE_ENDIAN */
#else /* BOOST_ENDIAN_LITTLE_BYTE */
char buffer[50];
// Convert the number of facets to little endian.
memcpy(buffer, &stl->stats.number_of_facets, 4);
@ -157,7 +157,7 @@ bool stl_write_binary(stl_file *stl, const char *file, const char *label)
stl_internal_reverse_quads(buffer, 48);
fwrite(buffer, SIZEOF_STL_FACET, 1, fp);
}
#endif /* BOOST_LITTLE_ENDIAN */
#endif /* BOOST_ENDIAN_LITTLE_BYTE */
fclose(fp);
return true;
}