This commit is contained in:
bubnikv 2018-08-22 15:03:35 +02:00
parent ac72cd779f
commit 6829704475
16 changed files with 539 additions and 908 deletions

View file

@ -51,31 +51,16 @@ TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd>& f
for (int i = 0; i < stl.stats.number_of_facets; i++) {
stl_facet facet;
const Vec3d& ref_f1 = points[facets[i](0)];
facet.vertex[0].x = ref_f1(0);
facet.vertex[0].y = ref_f1(1);
facet.vertex[0].z = ref_f1(2);
const Vec3d& ref_f2 = points[facets[i](1)];
facet.vertex[1].x = ref_f2(0);
facet.vertex[1].y = ref_f2(1);
facet.vertex[1].z = ref_f2(2);
const Vec3d& ref_f3 = points[facets[i](2)];
facet.vertex[2].x = ref_f3(0);
facet.vertex[2].y = ref_f3(1);
facet.vertex[2].z = ref_f3(2);
facet.vertex[0] = points[facets[i](0)].cast<float>();
facet.vertex[1] = points[facets[i](1)].cast<float>();
facet.vertex[2] = points[facets[i](2)].cast<float>();
facet.extra[0] = 0;
facet.extra[1] = 0;
float normal[3];
stl_normal normal;
stl_calculate_normal(normal, &facet);
stl_normalize_vector(normal);
facet.normal.x = normal[0];
facet.normal.y = normal[1];
facet.normal.z = normal[2];
facet.normal = normal;
stl.facet_start[i] = facet;
}
@ -302,11 +287,7 @@ void TriangleMesh::scale(float factor)
void TriangleMesh::scale(const Vec3d &versor)
{
float fversor[3];
fversor[0] = versor(0);
fversor[1] = versor(1);
fversor[2] = versor(2);
stl_scale_versor(&this->stl, fversor);
stl_scale_versor(&this->stl, versor.cast<float>());
stl_invalidate_shared_vertices(&this->stl);
}
@ -390,10 +371,9 @@ void TriangleMesh::transform(const float* matrix3x4)
void TriangleMesh::align_to_origin()
{
this->translate(
-(this->stl.stats.min.x),
-(this->stl.stats.min.y),
-(this->stl.stats.min.z)
);
- this->stl.stats.min(0),
- this->stl.stats.min(1),
- this->stl.stats.min(2));
}
void TriangleMesh::rotate(double angle, Point* center)
@ -518,7 +498,7 @@ TriangleMesh::split() const
stl_clear_error(&mesh->stl);
stl_allocate(&mesh->stl);
int first = 1;
bool first = true;
for (std::deque<int>::const_iterator facet = facets.begin(); facet != facets.end(); ++facet) {
mesh->stl.facet_start[facet - facets.begin()] = this->stl.facet_start[*facet];
stl_facet_stats(&mesh->stl, this->stl.facet_start[*facet], first);
@ -561,9 +541,9 @@ ExPolygons TriangleMesh::horizontal_projection() const
stl_facet* facet = &this->stl.facet_start[i];
Polygon p;
p.points.resize(3);
p.points[0] = Point::new_scale(facet->vertex[0].x, facet->vertex[0].y);
p.points[1] = Point::new_scale(facet->vertex[1].x, facet->vertex[1].y);
p.points[2] = Point::new_scale(facet->vertex[2].x, facet->vertex[2].y);
p.points[0] = Point::new_scale(facet->vertex[0](0), facet->vertex[0](1));
p.points[1] = Point::new_scale(facet->vertex[1](0), facet->vertex[1](1));
p.points[2] = Point::new_scale(facet->vertex[2](0), facet->vertex[2](1));
p.make_counter_clockwise(); // do this after scaling, as winding order might change while doing that
pp.emplace_back(p);
}
@ -578,8 +558,8 @@ Polygon TriangleMesh::convex_hull()
Points pp;
pp.reserve(this->stl.stats.shared_vertices);
for (int i = 0; i < this->stl.stats.shared_vertices; ++ i) {
stl_vertex* v = &this->stl.v_shared[i];
pp.emplace_back(Point::new_scale(v->x, v->y));
const stl_vertex &v = this->stl.v_shared[i];
pp.emplace_back(Point::new_scale(v(0), v(1)));
}
return Slic3r::Geometry::convex_hull(pp);
}
@ -589,12 +569,8 @@ TriangleMesh::bounding_box() const
{
BoundingBoxf3 bb;
bb.defined = true;
bb.min(0) = this->stl.stats.min.x;
bb.min(1) = this->stl.stats.min.y;
bb.min(2) = this->stl.stats.min.z;
bb.max(0) = this->stl.stats.max.x;
bb.max(1) = this->stl.stats.max.y;
bb.max(2) = this->stl.stats.max.z;
bb.min = this->stl.stats.min.cast<double>();
bb.max = this->stl.stats.max.cast<double>();
return bb;
}
@ -619,11 +595,8 @@ TriangleMeshSlicer::TriangleMeshSlicer(TriangleMesh* _mesh) :
facets_edges.assign(_mesh->stl.stats.number_of_facets * 3, -1);
v_scaled_shared.assign(_mesh->stl.v_shared, _mesh->stl.v_shared + _mesh->stl.stats.shared_vertices);
// Scale the copied vertices.
for (int i = 0; i < this->mesh->stl.stats.shared_vertices; ++ i) {
this->v_scaled_shared[i].x /= float(SCALING_FACTOR);
this->v_scaled_shared[i].y /= float(SCALING_FACTOR);
this->v_scaled_shared[i].z /= float(SCALING_FACTOR);
}
for (int i = 0; i < this->mesh->stl.stats.shared_vertices; ++ i)
this->v_scaled_shared[i] *= float(1. / SCALING_FACTOR);
// Create a mapping from triangle edge into face.
struct EdgeToFace {
@ -779,14 +752,14 @@ void TriangleMeshSlicer::_slice_do(size_t facet_idx, std::vector<IntersectionLin
const stl_facet &facet = this->mesh->stl.facet_start[facet_idx];
// find facet extents
const float min_z = fminf(facet.vertex[0].z, fminf(facet.vertex[1].z, facet.vertex[2].z));
const float max_z = fmaxf(facet.vertex[0].z, fmaxf(facet.vertex[1].z, facet.vertex[2].z));
const float min_z = fminf(facet.vertex[0](2), fminf(facet.vertex[1](2), facet.vertex[2](2)));
const float max_z = fmaxf(facet.vertex[0](2), fmaxf(facet.vertex[1](2), facet.vertex[2](2)));
#ifdef SLIC3R_DEBUG
printf("\n==> FACET %d (%f,%f,%f - %f,%f,%f - %f,%f,%f):\n", facet_idx,
facet.vertex[0].x, facet.vertex[0].y, facet.vertex[0].z,
facet.vertex[1].x, facet.vertex[1].y, facet.vertex[1].z,
facet.vertex[2].x, facet.vertex[2].y, facet.vertex[2].z);
facet.vertex[0].x, facet.vertex[0].y, facet.vertex[0](2),
facet.vertex[1].x, facet.vertex[1].y, facet.vertex[1](2),
facet.vertex[2].x, facet.vertex[2].y, facet.vertex[2](2));
printf("z: min = %.2f, max = %.2f\n", min_z, max_z);
#endif
@ -806,18 +779,18 @@ void TriangleMeshSlicer::_slice_do(size_t facet_idx, std::vector<IntersectionLin
if (il.edge_type == feHorizontal) {
// Insert all three edges of the face.
const int *vertices = this->mesh->stl.v_indices[facet_idx].vertex;
const bool reverse = this->mesh->stl.facet_start[facet_idx].normal.z < 0;
const bool reverse = this->mesh->stl.facet_start[facet_idx].normal(2) < 0;
for (int j = 0; j < 3; ++ j) {
int a_id = vertices[j % 3];
int b_id = vertices[(j+1) % 3];
if (reverse)
std::swap(a_id, b_id);
const stl_vertex *a = &this->v_scaled_shared[a_id];
const stl_vertex *b = &this->v_scaled_shared[b_id];
il.a(0) = a->x;
il.a(1) = a->y;
il.b(0) = b->x;
il.b(1) = b->y;
const stl_vertex &a = this->v_scaled_shared[a_id];
const stl_vertex &b = this->v_scaled_shared[b_id];
il.a(0) = a(0);
il.a(1) = a(1);
il.b(0) = b(0);
il.b(1) = b(1);
il.a_id = a_id;
il.b_id = b_id;
(*lines)[layer_idx].emplace_back(il);
@ -863,66 +836,63 @@ bool TriangleMeshSlicer::slice_facet(
// Reorder vertices so that the first one is the one with lowest Z.
// This is needed to get all intersection lines in a consistent order
// (external on the right of the line)
int i = (facet.vertex[1].z == min_z) ? 1 : ((facet.vertex[2].z == min_z) ? 2 : 0);
int i = (facet.vertex[1](2) == min_z) ? 1 : ((facet.vertex[2](2) == min_z) ? 2 : 0);
for (int j = i; j - i < 3; ++ j) { // loop through facet edges
int edge_id = this->facets_edges[facet_idx * 3 + (j % 3)];
const int *vertices = this->mesh->stl.v_indices[facet_idx].vertex;
int a_id = vertices[j % 3];
int b_id = vertices[(j+1) % 3];
const stl_vertex *a = &this->v_scaled_shared[a_id];
const stl_vertex *b = &this->v_scaled_shared[b_id];
const stl_vertex &a = this->v_scaled_shared[a_id];
const stl_vertex &b = this->v_scaled_shared[b_id];
// Is edge or face aligned with the cutting plane?
if (a->z == slice_z && b->z == slice_z) {
if (a(2) == slice_z && b(2) == slice_z) {
// Edge is horizontal and belongs to the current layer.
const stl_vertex &v0 = this->v_scaled_shared[vertices[0]];
const stl_vertex &v1 = this->v_scaled_shared[vertices[1]];
const stl_vertex &v2 = this->v_scaled_shared[vertices[2]];
bool swap = false;
if (min_z == max_z) {
// All three vertices are aligned with slice_z.
line_out->edge_type = feHorizontal;
if (this->mesh->stl.facet_start[facet_idx].normal.z < 0) {
if (this->mesh->stl.facet_start[facet_idx].normal(2) < 0) {
// If normal points downwards this is a bottom horizontal facet so we reverse its point order.
std::swap(a, b);
std::swap(a_id, b_id);
swap = true;
}
} else if (v0.z < slice_z || v1.z < slice_z || v2.z < slice_z) {
} else if (v0(2) < slice_z || v1(2) < slice_z || v2(2) < slice_z) {
// Two vertices are aligned with the cutting plane, the third vertex is below the cutting plane.
line_out->edge_type = feTop;
std::swap(a, b);
std::swap(a_id, b_id);
swap = true;
} else {
// Two vertices are aligned with the cutting plane, the third vertex is above the cutting plane.
line_out->edge_type = feBottom;
}
line_out->a(0) = a->x;
line_out->a(1) = a->y;
line_out->b(0) = b->x;
line_out->b(1) = b->y;
line_out->a_id = a_id;
line_out->b_id = b_id;
line_out->a = to_2d(swap ? b : a).cast<coord_t>();
line_out->b = to_2d(swap ? a : b).cast<coord_t>();
line_out->a_id = swap ? b_id : a_id;
line_out->b_id = swap ? a_id : b_id;
return true;
}
if (a->z == slice_z) {
if (a(2) == slice_z) {
// Only point a alings with the cutting plane.
points_on_layer[num_points_on_layer ++] = num_points;
IntersectionPoint &point = points[num_points ++];
point(0) = a->x;
point(1) = a->y;
point(0) = a(0);
point(1) = a(1);
point.point_id = a_id;
} else if (b->z == slice_z) {
} else if (b(2) == slice_z) {
// Only point b alings with the cutting plane.
points_on_layer[num_points_on_layer ++] = num_points;
IntersectionPoint &point = points[num_points ++];
point(0) = b->x;
point(1) = b->y;
point(0) = b(0);
point(1) = b(1);
point.point_id = b_id;
} else if ((a->z < slice_z && b->z > slice_z) || (b->z < slice_z && a->z > slice_z)) {
} else if ((a(2) < slice_z && b(2) > slice_z) || (b(2) < slice_z && a(2) > slice_z)) {
// A general case. The face edge intersects the cutting plane. Calculate the intersection point.
IntersectionPoint &point = points[num_points ++];
point(0) = b->x + (a->x - b->x) * (slice_z - b->z) / (a->z - b->z);
point(1) = b->y + (a->y - b->y) * (slice_z - b->z) / (a->z - b->z);
point(0) = b(0) + (a(0) - b(0)) * (slice_z - b(2)) / (a(2) - b(2));
point(1) = b(1) + (a(1) - b(1)) * (slice_z - b(2)) / (a(2) - b(2));
point.edge_id = edge_id;
}
}
@ -1389,8 +1359,8 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
stl_facet* facet = &this->mesh->stl.facet_start[facet_idx];
// find facet extents
float min_z = std::min(facet->vertex[0].z, std::min(facet->vertex[1].z, facet->vertex[2].z));
float max_z = std::max(facet->vertex[0].z, std::max(facet->vertex[1].z, facet->vertex[2].z));
float min_z = std::min(facet->vertex[0](2), std::min(facet->vertex[1](2), facet->vertex[2](2)));
float max_z = std::max(facet->vertex[0](2), std::max(facet->vertex[1](2), facet->vertex[2](2)));
// intersect facet with cutting plane
IntersectionLine line;
@ -1417,47 +1387,47 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
// look for the vertex on whose side of the slicing plane there are no other vertices
int isolated_vertex;
if ( (facet->vertex[0].z > z) == (facet->vertex[1].z > z) ) {
if ( (facet->vertex[0](2) > z) == (facet->vertex[1](2) > z) ) {
isolated_vertex = 2;
} else if ( (facet->vertex[1].z > z) == (facet->vertex[2].z > z) ) {
} else if ( (facet->vertex[1](2) > z) == (facet->vertex[2](2) > z) ) {
isolated_vertex = 0;
} else {
isolated_vertex = 1;
}
// get vertices starting from the isolated one
stl_vertex* v0 = &facet->vertex[isolated_vertex];
stl_vertex* v1 = &facet->vertex[(isolated_vertex+1) % 3];
stl_vertex* v2 = &facet->vertex[(isolated_vertex+2) % 3];
const stl_vertex &v0 = facet->vertex[isolated_vertex];
const stl_vertex &v1 = facet->vertex[(isolated_vertex+1) % 3];
const stl_vertex &v2 = facet->vertex[(isolated_vertex+2) % 3];
// intersect v0-v1 and v2-v0 with cutting plane and make new vertices
stl_vertex v0v1, v2v0;
v0v1.x = v1->x + (v0->x - v1->x) * (z - v1->z) / (v0->z - v1->z);
v0v1.y = v1->y + (v0->y - v1->y) * (z - v1->z) / (v0->z - v1->z);
v0v1.z = z;
v2v0.x = v2->x + (v0->x - v2->x) * (z - v2->z) / (v0->z - v2->z);
v2v0.y = v2->y + (v0->y - v2->y) * (z - v2->z) / (v0->z - v2->z);
v2v0.z = z;
v0v1(0) = v1(0) + (v0(0) - v1(0)) * (z - v1(2)) / (v0(2) - v1(2));
v0v1(1) = v1(1) + (v0(1) - v1(1)) * (z - v1(2)) / (v0(2) - v1(2));
v0v1(2) = z;
v2v0(0) = v2(0) + (v0(0) - v2(0)) * (z - v2(2)) / (v0(2) - v2(2));
v2v0(1) = v2(1) + (v0(1) - v2(1)) * (z - v2(2)) / (v0(2) - v2(2));
v2v0(2) = z;
// build the triangular facet
stl_facet triangle;
triangle.normal = facet->normal;
triangle.vertex[0] = *v0;
triangle.vertex[0] = v0;
triangle.vertex[1] = v0v1;
triangle.vertex[2] = v2v0;
// build the facets forming a quadrilateral on the other side
stl_facet quadrilateral[2];
quadrilateral[0].normal = facet->normal;
quadrilateral[0].vertex[0] = *v1;
quadrilateral[0].vertex[1] = *v2;
quadrilateral[0].vertex[0] = v1;
quadrilateral[0].vertex[1] = v2;
quadrilateral[0].vertex[2] = v0v1;
quadrilateral[1].normal = facet->normal;
quadrilateral[1].vertex[0] = *v2;
quadrilateral[1].vertex[0] = v2;
quadrilateral[1].vertex[1] = v2v0;
quadrilateral[1].vertex[2] = v0v1;
if (v0->z > z) {
if (v0(2) > z) {
if (upper != NULL) stl_add_facet(&upper->stl, &triangle);
if (lower != NULL) {
stl_add_facet(&lower->stl, &quadrilateral[0]);
@ -1489,13 +1459,11 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
Polygon p = *polygon;
p.reverse();
stl_facet facet;
facet.normal.x = 0;
facet.normal.y = 0;
facet.normal.z = -1;
facet.normal = stl_normal(0, 0, -1.f);
for (size_t i = 0; i <= 2; ++i) {
facet.vertex[i].x = unscale<float>(p.points[i](0));
facet.vertex[i].y = unscale<float>(p.points[i](1));
facet.vertex[i].z = z;
facet.vertex[i](0) = unscale<float>(p.points[i](0));
facet.vertex[i](1) = unscale<float>(p.points[i](1));
facet.vertex[i](2) = z;
}
stl_add_facet(&upper->stl, &facet);
}
@ -1515,13 +1483,11 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
// convert triangles to facets and append them to mesh
for (Polygons::const_iterator polygon = triangles.begin(); polygon != triangles.end(); ++polygon) {
stl_facet facet;
facet.normal.x = 0;
facet.normal.y = 0;
facet.normal.z = 1;
facet.normal = stl_normal(0, 0, 1.f);
for (size_t i = 0; i <= 2; ++i) {
facet.vertex[i].x = unscale<float>(polygon->points[i](0));
facet.vertex[i].y = unscale<float>(polygon->points[i](1));
facet.vertex[i].z = z;
facet.vertex[i](0) = unscale<float>(polygon->points[i](0));
facet.vertex[i](1) = unscale<float>(polygon->points[i](1));
facet.vertex[i](2) = z;
}
stl_add_facet(&lower->stl, &facet);
}