mirror of
https://git.mirrors.martin98.com/https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-14 04:36:09 +08:00
Improvements of admesh robustness when loading and fixing STLs.
https://github.com/prusa3d/Slic3r/issues/33
This commit is contained in:
parent
d1d6e907c5
commit
52de3940fe
@ -106,53 +106,42 @@ stl_check_facets_exact(stl_file *stl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
stl_free_edges(stl);
|
stl_free_edges(stl);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("Number of faces: %d, number of manifold edges: %d, number of connected edges: %d, number of unconnected edges: %d\r\n",
|
||||||
|
stl->stats.number_of_facets, stl->stats.number_of_facets * 3,
|
||||||
|
stl->stats.connected_edges, stl->stats.number_of_facets * 3 - stl->stats.connected_edges);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stl_load_edge_exact(stl_file *stl, stl_hash_edge *edge,
|
stl_load_edge_exact(stl_file *stl, stl_hash_edge *edge,
|
||||||
stl_vertex *a, stl_vertex *b) {
|
stl_vertex *a, stl_vertex *b) {
|
||||||
|
|
||||||
float diff_x;
|
|
||||||
float diff_y;
|
|
||||||
float diff_z;
|
|
||||||
float max_diff;
|
|
||||||
|
|
||||||
if (stl->error) return;
|
if (stl->error) return;
|
||||||
|
|
||||||
diff_x = ABS(a->x - b->x);
|
{
|
||||||
diff_y = ABS(a->y - b->y);
|
float diff_x = ABS(a->x - b->x);
|
||||||
diff_z = ABS(a->z - b->z);
|
float diff_y = ABS(a->y - b->y);
|
||||||
max_diff = STL_MAX(diff_x, diff_y);
|
float diff_z = ABS(a->z - b->z);
|
||||||
max_diff = STL_MAX(diff_z, max_diff);
|
float max_diff = STL_MAX(diff_x, diff_y);
|
||||||
stl->stats.shortest_edge = STL_MIN(max_diff, stl->stats.shortest_edge);
|
max_diff = STL_MAX(diff_z, max_diff);
|
||||||
|
stl->stats.shortest_edge = STL_MIN(max_diff, stl->stats.shortest_edge);
|
||||||
|
}
|
||||||
|
|
||||||
if(diff_x == max_diff) {
|
// Ensure identical vertex ordering of equal edges.
|
||||||
if(a->x > b->x) {
|
// This method is numerically robust.
|
||||||
memcpy(&edge->key[0], a, sizeof(stl_vertex));
|
if ((a->x != b->x) ?
|
||||||
memcpy(&edge->key[3], b, sizeof(stl_vertex));
|
(a->x < b->x) :
|
||||||
} else {
|
((a->y != b->y) ?
|
||||||
memcpy(&edge->key[0], b, sizeof(stl_vertex));
|
(a->y < b->y) :
|
||||||
memcpy(&edge->key[3], a, sizeof(stl_vertex));
|
(a->z < b->z))) {
|
||||||
edge->which_edge += 3; /* this edge is loaded backwards */
|
memcpy(&edge->key[0], a, sizeof(stl_vertex));
|
||||||
}
|
memcpy(&edge->key[3], b, sizeof(stl_vertex));
|
||||||
} else if(diff_y == max_diff) {
|
|
||||||
if(a->y > b->y) {
|
|
||||||
memcpy(&edge->key[0], a, sizeof(stl_vertex));
|
|
||||||
memcpy(&edge->key[3], b, sizeof(stl_vertex));
|
|
||||||
} else {
|
|
||||||
memcpy(&edge->key[0], b, sizeof(stl_vertex));
|
|
||||||
memcpy(&edge->key[3], a, sizeof(stl_vertex));
|
|
||||||
edge->which_edge += 3; /* this edge is loaded backwards */
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if(a->z > b->z) {
|
memcpy(&edge->key[0], b, sizeof(stl_vertex));
|
||||||
memcpy(&edge->key[0], a, sizeof(stl_vertex));
|
memcpy(&edge->key[3], a, sizeof(stl_vertex));
|
||||||
memcpy(&edge->key[3], b, sizeof(stl_vertex));
|
edge->which_edge += 3; /* this edge is loaded backwards */
|
||||||
} else {
|
|
||||||
memcpy(&edge->key[0], b, sizeof(stl_vertex));
|
|
||||||
memcpy(&edge->key[3], a, sizeof(stl_vertex));
|
|
||||||
edge->which_edge += 3; /* this edge is loaded backwards */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,26 +298,17 @@ stl_check_facets_nearby(stl_file *stl, float tolerance) {
|
|||||||
static int
|
static int
|
||||||
stl_load_edge_nearby(stl_file *stl, stl_hash_edge *edge,
|
stl_load_edge_nearby(stl_file *stl, stl_hash_edge *edge,
|
||||||
stl_vertex *a, stl_vertex *b, float tolerance) {
|
stl_vertex *a, stl_vertex *b, float tolerance) {
|
||||||
float diff_x;
|
// Index of a grid cell spaced by tolerance.
|
||||||
float diff_y;
|
uint32_t vertex1[3] = {
|
||||||
float diff_z;
|
(uint32_t)((a->x - stl->stats.min.x) / tolerance),
|
||||||
float max_diff;
|
(uint32_t)((a->y - stl->stats.min.y) / tolerance),
|
||||||
unsigned vertex1[3];
|
(uint32_t)((a->z - stl->stats.min.z) / tolerance)
|
||||||
unsigned vertex2[3];
|
};
|
||||||
|
uint32_t vertex2[3] = {
|
||||||
|
(uint32_t)((b->x - stl->stats.min.x) / tolerance),
|
||||||
diff_x = ABS(a->x - b->x);
|
(uint32_t)((b->y - stl->stats.min.y) / tolerance),
|
||||||
diff_y = ABS(a->y - b->y);
|
(uint32_t)((b->z - stl->stats.min.z) / tolerance)
|
||||||
diff_z = ABS(a->z - b->z);
|
};
|
||||||
max_diff = STL_MAX(diff_x, diff_y);
|
|
||||||
max_diff = STL_MAX(diff_z, max_diff);
|
|
||||||
|
|
||||||
vertex1[0] = (unsigned)((a->x - stl->stats.min.x) / tolerance);
|
|
||||||
vertex1[1] = (unsigned)((a->y - stl->stats.min.y) / tolerance);
|
|
||||||
vertex1[2] = (unsigned)((a->z - stl->stats.min.z) / tolerance);
|
|
||||||
vertex2[0] = (unsigned)((b->x - stl->stats.min.x) / tolerance);
|
|
||||||
vertex2[1] = (unsigned)((b->y - stl->stats.min.y) / tolerance);
|
|
||||||
vertex2[2] = (unsigned)((b->z - stl->stats.min.z) / tolerance);
|
|
||||||
|
|
||||||
if( (vertex1[0] == vertex2[0])
|
if( (vertex1[0] == vertex2[0])
|
||||||
&& (vertex1[1] == vertex2[1])
|
&& (vertex1[1] == vertex2[1])
|
||||||
@ -337,33 +317,19 @@ stl_load_edge_nearby(stl_file *stl, stl_hash_edge *edge,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(diff_x == max_diff) {
|
// Ensure identical vertex ordering of edges, which vertices land into equal grid cells.
|
||||||
if(a->x > b->x) {
|
// This method is numerically robust.
|
||||||
memcpy(&edge->key[0], vertex1, sizeof(stl_vertex));
|
if ((vertex1[0] != vertex2[0]) ?
|
||||||
memcpy(&edge->key[3], vertex2, sizeof(stl_vertex));
|
(vertex1[0] < vertex2[0]) :
|
||||||
} else {
|
((vertex1[1] != vertex2[1]) ?
|
||||||
memcpy(&edge->key[0], vertex2, sizeof(stl_vertex));
|
(vertex1[1] < vertex2[1]) :
|
||||||
memcpy(&edge->key[3], vertex1, sizeof(stl_vertex));
|
(vertex1[2] < vertex2[2]))) {
|
||||||
edge->which_edge += 3; /* this edge is loaded backwards */
|
memcpy(&edge->key[0], vertex1, sizeof(stl_vertex));
|
||||||
}
|
memcpy(&edge->key[3], vertex2, sizeof(stl_vertex));
|
||||||
} else if(diff_y == max_diff) {
|
|
||||||
if(a->y > b->y) {
|
|
||||||
memcpy(&edge->key[0], vertex1, sizeof(stl_vertex));
|
|
||||||
memcpy(&edge->key[3], vertex2, sizeof(stl_vertex));
|
|
||||||
} else {
|
|
||||||
memcpy(&edge->key[0], vertex2, sizeof(stl_vertex));
|
|
||||||
memcpy(&edge->key[3], vertex1, sizeof(stl_vertex));
|
|
||||||
edge->which_edge += 3; /* this edge is loaded backwards */
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if(a->z > b->z) {
|
memcpy(&edge->key[0], vertex2, sizeof(stl_vertex));
|
||||||
memcpy(&edge->key[0], vertex1, sizeof(stl_vertex));
|
memcpy(&edge->key[3], vertex1, sizeof(stl_vertex));
|
||||||
memcpy(&edge->key[3], vertex2, sizeof(stl_vertex));
|
edge->which_edge += 3; /* this edge is loaded backwards */
|
||||||
} else {
|
|
||||||
memcpy(&edge->key[0], vertex2, sizeof(stl_vertex));
|
|
||||||
memcpy(&edge->key[3], vertex1, sizeof(stl_vertex));
|
|
||||||
edge->which_edge += 3; /* this edge is loaded backwards */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -564,6 +530,33 @@ stl_change_vertices(stl_file *stl, int facet_num, int vnot,
|
|||||||
next_edge = pivot_vertex;
|
next_edge = pivot_vertex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
if (stl->facet_start[facet_num].vertex[pivot_vertex].x == new_vertex.x &&
|
||||||
|
stl->facet_start[facet_num].vertex[pivot_vertex].y == new_vertex.y &&
|
||||||
|
stl->facet_start[facet_num].vertex[pivot_vertex].z == new_vertex.z)
|
||||||
|
printf("Changing vertex %f,%f,%f: Same !!!\r\n",
|
||||||
|
new_vertex.x, new_vertex.y, new_vertex.z);
|
||||||
|
else {
|
||||||
|
if (stl->facet_start[facet_num].vertex[pivot_vertex].x != new_vertex.x)
|
||||||
|
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
|
||||||
|
stl->facet_start[facet_num].vertex[pivot_vertex].x,
|
||||||
|
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex].x),
|
||||||
|
new_vertex.x,
|
||||||
|
*reinterpret_cast<const int*>(&new_vertex.x));
|
||||||
|
if (stl->facet_start[facet_num].vertex[pivot_vertex].y != new_vertex.y)
|
||||||
|
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
|
||||||
|
stl->facet_start[facet_num].vertex[pivot_vertex].y,
|
||||||
|
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex].y),
|
||||||
|
new_vertex.y,
|
||||||
|
*reinterpret_cast<const int*>(&new_vertex.y));
|
||||||
|
if (stl->facet_start[facet_num].vertex[pivot_vertex].z != new_vertex.z)
|
||||||
|
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
|
||||||
|
stl->facet_start[facet_num].vertex[pivot_vertex].z,
|
||||||
|
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex].z),
|
||||||
|
new_vertex.z,
|
||||||
|
*reinterpret_cast<const int*>(&new_vertex.z));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
stl->facet_start[facet_num].vertex[pivot_vertex] = new_vertex;
|
stl->facet_start[facet_num].vertex[pivot_vertex] = new_vertex;
|
||||||
vnot = stl->neighbors_start[facet_num].which_vertex_not[next_edge];
|
vnot = stl->neighbors_start[facet_num].which_vertex_not[next_edge];
|
||||||
facet_num = stl->neighbors_start[facet_num].neighbor[next_edge];
|
facet_num = stl->neighbors_start[facet_num].neighbor[next_edge];
|
||||||
|
@ -77,7 +77,10 @@ typedef struct {
|
|||||||
typedef struct stl_hash_edge {
|
typedef struct stl_hash_edge {
|
||||||
// Key of a hash edge: 2x binary copy of a floating point vertex.
|
// Key of a hash edge: 2x binary copy of a floating point vertex.
|
||||||
uint32_t key[6];
|
uint32_t key[6];
|
||||||
|
// 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;
|
int which_edge;
|
||||||
struct stl_hash_edge *next;
|
struct stl_hash_edge *next;
|
||||||
} stl_hash_edge;
|
} stl_hash_edge;
|
||||||
|
@ -284,20 +284,6 @@ stl_read(stl_file *stl, int first_facet, int first) {
|
|||||||
stl->error = 1;
|
stl->error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
// 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.
|
|
||||||
// It may be worth to round these numbers to zero during loading to reduce the number of errors reported
|
|
||||||
// during the STL import.
|
|
||||||
for (size_t j = 0; j < 3; ++ j) {
|
|
||||||
if (facet.vertex[j].x > -1e-12f && facet.vertex[j].x < 1e-12f)
|
|
||||||
printf("stl_read: facet %d.x = %e\r\n", j, facet.vertex[j].x);
|
|
||||||
if (facet.vertex[j].y > -1e-12f && facet.vertex[j].y < 1e-12f)
|
|
||||||
printf("stl_read: facet %d.y = %e\r\n", j, facet.vertex[j].y);
|
|
||||||
if (facet.vertex[j].z > -1e-12f && facet.vertex[j].z < 1e-12f)
|
|
||||||
printf("stl_read: facet %d.z = %e\r\n", j, facet.vertex[j].z);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else
|
} else
|
||||||
/* Read a single facet from an ASCII .STL file */
|
/* Read a single facet from an ASCII .STL file */
|
||||||
{
|
{
|
||||||
@ -319,6 +305,21 @@ stl_read(stl_file *stl, int first_facet, int first) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// 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.
|
||||||
|
// It may be worth to round these numbers to zero during loading to reduce the number of errors reported
|
||||||
|
// during the STL import.
|
||||||
|
for (size_t j = 0; j < 3; ++ j) {
|
||||||
|
if (facet.vertex[j].x > -1e-12f && facet.vertex[j].x < 1e-12f)
|
||||||
|
printf("stl_read: facet %d.x = %e\r\n", j, facet.vertex[j].x);
|
||||||
|
if (facet.vertex[j].y > -1e-12f && facet.vertex[j].y < 1e-12f)
|
||||||
|
printf("stl_read: facet %d.y = %e\r\n", j, facet.vertex[j].y);
|
||||||
|
if (facet.vertex[j].z > -1e-12f && facet.vertex[j].z < 1e-12f)
|
||||||
|
printf("stl_read: facet %d.z = %e\r\n", j, facet.vertex[j].z);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
{
|
{
|
||||||
// Positive and negative zeros are possible in the floats, which are considered equal by the FP unit.
|
// Positive and negative zeros are possible in the floats, which are considered equal by the FP unit.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user