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

@ -1485,7 +1485,7 @@ namespace Slic3r {
stl_facet& facet = stl.facet_start[i];
for (unsigned int v = 0; v < 3; ++v)
{
::memcpy((void*)&facet.vertex[v].x, (const void*)&geometry.vertices[geometry.triangles[src_start_id + ii + v] * 3], 3 * sizeof(float));
::memcpy(facet.vertex[v].data(), (const void*)&geometry.vertices[geometry.triangles[src_start_id + ii + v] * 3], 3 * sizeof(float));
}
}
@ -1844,9 +1844,9 @@ namespace Slic3r {
for (int i = 0; i < stl.stats.shared_vertices; ++i)
{
stream << " <" << VERTEX_TAG << " ";
stream << "x=\"" << stl.v_shared[i].x << "\" ";
stream << "y=\"" << stl.v_shared[i].y << "\" ";
stream << "z=\"" << stl.v_shared[i].z << "\" />\n";
stream << "x=\"" << stl.v_shared[i](0) << "\" ";
stream << "y=\"" << stl.v_shared[i](1) << "\" ";
stream << "z=\"" << stl.v_shared[i](2) << "\" />\n";
}
}

View file

@ -402,7 +402,7 @@ void AMFParserContext::endElement(const char * /* name */)
for (size_t i = 0; i < m_volume_facets.size();) {
stl_facet &facet = stl.facet_start[i/3];
for (unsigned int v = 0; v < 3; ++ v)
memcpy(&facet.vertex[v].x, &m_object_vertices[m_volume_facets[i ++] * 3], 3 * sizeof(float));
memcpy(facet.vertex[v].data(), &m_object_vertices[m_volume_facets[i ++] * 3], 3 * sizeof(float));
}
stl_get_size(&stl);
m_volume->mesh.repair();
@ -760,9 +760,9 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c
for (size_t i = 0; i < stl.stats.shared_vertices; ++ i) {
stream << " <vertex>\n";
stream << " <coordinates>\n";
stream << " <x>" << stl.v_shared[i].x << "</x>\n";
stream << " <y>" << stl.v_shared[i].y << "</y>\n";
stream << " <z>" << stl.v_shared[i].z << "</z>\n";
stream << " <x>" << stl.v_shared[i](0) << "</x>\n";
stream << " <y>" << stl.v_shared[i](1) << "</y>\n";
stream << " <z>" << stl.v_shared[i](2) << "</z>\n";
stream << " </coordinates>\n";
stream << " </vertex>\n";
}

View file

@ -57,14 +57,14 @@ bool load_obj(const char *path, Model *model, const char *object_name_in)
continue;
stl_facet &facet = stl.facet_start[i_face ++];
size_t num_normals = 0;
stl_normal normal = { 0.f };
stl_normal normal(stl_normal::Zero());
for (unsigned int v = 0; v < 3; ++ v) {
const ObjParser::ObjVertex &vertex = data.vertices[i++];
memcpy(&facet.vertex[v].x, &data.coordinates[vertex.coordIdx*4], 3 * sizeof(float));
memcpy(facet.vertex[v].data(), &data.coordinates[vertex.coordIdx*4], 3 * sizeof(float));
if (vertex.normalIdx != -1) {
normal.x += data.normals[vertex.normalIdx*3];
normal.y += data.normals[vertex.normalIdx*3+1];
normal.z += data.normals[vertex.normalIdx*3+2];
normal(0) += data.normals[vertex.normalIdx*3];
normal(1) += data.normals[vertex.normalIdx*3+1];
normal(2) += data.normals[vertex.normalIdx*3+2];
++ num_normals;
}
}
@ -74,33 +74,27 @@ bool load_obj(const char *path, Model *model, const char *object_name_in)
facet2.vertex[0] = facet.vertex[0];
facet2.vertex[1] = facet.vertex[2];
const ObjParser::ObjVertex &vertex = data.vertices[i++];
memcpy(&facet2.vertex[2].x, &data.coordinates[vertex.coordIdx * 4], 3 * sizeof(float));
memcpy(facet2.vertex[2].data(), &data.coordinates[vertex.coordIdx * 4], 3 * sizeof(float));
if (vertex.normalIdx != -1) {
normal.x += data.normals[vertex.normalIdx*3];
normal.y += data.normals[vertex.normalIdx*3+1];
normal.z += data.normals[vertex.normalIdx*3+2];
normal(0) += data.normals[vertex.normalIdx*3];
normal(1) += data.normals[vertex.normalIdx*3+1];
normal(2) += data.normals[vertex.normalIdx*3+2];
++ num_normals;
}
if (num_normals == 4) {
// Normalize an average normal of a quad.
float len = sqrt(facet.normal.x*facet.normal.x + facet.normal.y*facet.normal.y + facet.normal.z*facet.normal.z);
float len = facet.normal.norm();
if (len > EPSILON) {
normal.x /= len;
normal.y /= len;
normal.z /= len;
normal /= len;
facet.normal = normal;
facet2.normal = normal;
}
}
} else if (num_normals == 3) {
// Normalize an average normal of a triangle.
float len = sqrt(facet.normal.x*facet.normal.x + facet.normal.y*facet.normal.y + facet.normal.z*facet.normal.z);
if (len > EPSILON) {
normal.x /= len;
normal.y /= len;
normal.z /= len;
facet.normal = normal;
}
float len = facet.normal.norm();
if (len > EPSILON)
facet.normal = normal / len;
}
}
stl_get_size(&stl);

View file

@ -260,8 +260,8 @@ bool load_prus(const char *path, Model *model)
mesh.repair();
// Transform the model.
stl_transform(&stl, &trafo[0][0]);
if (std::abs(stl.stats.min.z) < EPSILON)
stl.stats.min.z = 0.;
if (std::abs(stl.stats.min(2)) < EPSILON)
stl.stats.min(2) = 0.;
// Add a mesh to a model.
if (mesh.facets_count() > 0)
mesh_valid = true;
@ -309,11 +309,11 @@ bool load_prus(const char *path, Model *model)
assert(res_normal == 3);
int res_outer_loop = line_reader.next_line_scanf(" outer loop");
assert(res_outer_loop == 0);
int res_vertex1 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[0].x, &facet.vertex[0].y, &facet.vertex[0].z);
int res_vertex1 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[0](0), &facet.vertex[0](1), &facet.vertex[0](2));
assert(res_vertex1 == 3);
int res_vertex2 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[1].x, &facet.vertex[1].y, &facet.vertex[1].z);
int res_vertex2 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[1](0), &facet.vertex[1](1), &facet.vertex[1](2));
assert(res_vertex2 == 3);
int res_vertex3 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[2].x, &facet.vertex[2].y, &facet.vertex[2].z);
int res_vertex3 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[2](0), &facet.vertex[2](1), &facet.vertex[2](2));
assert(res_vertex3 == 3);
int res_endloop = line_reader.next_line_scanf(" endloop");
assert(res_endloop == 0);
@ -324,9 +324,9 @@ bool load_prus(const char *path, Model *model)
break;
}
// 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.x) != 1 ||
sscanf(normal_buf[1], "%f", &facet.normal.y) != 1 ||
sscanf(normal_buf[2], "%f", &facet.normal.z) != 1) {
if (sscanf(normal_buf[0], "%f", &facet.normal(0)) != 1 ||
sscanf(normal_buf[1], "%f", &facet.normal(1)) != 1 ||
sscanf(normal_buf[2], "%f", &facet.normal(2)) != 1) {
// Normal was mangled. Maybe denormals or "not a number" were stored?
// Just reset the normal and silently ignore it.
memset(&facet.normal, 0, sizeof(facet.normal));

View file

@ -642,24 +642,13 @@ BoundingBoxf3 ModelObject::tight_bounding_box(bool include_modifiers) const
{
// original point
const stl_vertex& v = facet.vertex[i];
Vec3d p((double)v.x, (double)v.y, (double)v.z);
// scale
p(0) *= inst->scaling_factor;
p(1) *= inst->scaling_factor;
p(2) *= inst->scaling_factor;
// rotate Z
double x = p(0);
double y = p(1);
p(0) = c * x - s * y;
p(1) = s * x + c * y;
// translate
p(0) += inst->offset(0);
p(1) += inst->offset(1);
bb.merge(p);
Vec3d p = v.cast<double>() * inst->scaling_factor;
// rotate Z, translate
Vec3d q(c * p(0) - s * p(1) + inst->offset(0),
s * p(0) + c * p(1) + inst->offset(1),
p(2));
bb.merge(q);
}
}
}
@ -770,7 +759,7 @@ void ModelObject::rotate(float angle, const Axis &axis)
for (ModelVolume *v : this->volumes)
{
v->mesh.rotate(angle, axis);
min_z = std::min(min_z, v->mesh.stl.stats.min.z);
min_z = std::min(min_z, v->mesh.stl.stats.min(2));
}
if (min_z != 0.0f)
@ -927,24 +916,13 @@ void ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_
{
// original point
const stl_vertex& v = facet.vertex[i];
Vec3d p((double)v.x, (double)v.y, (double)v.z);
// scale
p(0) *= inst->scaling_factor;
p(1) *= inst->scaling_factor;
p(2) *= inst->scaling_factor;
Vec3d p = v.cast<double>() * inst->scaling_factor;
// rotate Z
double x = p(0);
double y = p(1);
p(0) = c * x - s * y;
p(1) = s * x + c * y;
// translate
p(0) += inst->offset(0);
p(1) += inst->offset(1);
bb.merge(p);
bb.merge(Vec3d(
c * p(0) - s * p(1) + inst->offset(0),
s * p(0) + c * p(1) + inst->offset(1),
p(2)));
}
}
@ -1081,7 +1059,7 @@ BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mes
const stl_facet &facet = mesh->stl.facet_start[i];
for (int j = 0; j < 3; ++ j) {
const stl_vertex &v = facet.vertex[j];
bbox.merge(Vec3d(c * v.x - s * v.y, s * v.x + c * v.y, v.z));
bbox.merge(Vec3d(c * v(0) - s * v(1), s * v(0) + c * v(1), v(2)));
}
}
if (! empty(bbox)) {

View file

@ -15,8 +15,8 @@ void SlicingAdaptive::clear()
std::pair<float, float> face_z_span(const stl_facet *f)
{
return std::pair<float, float>(
std::min(std::min(f->vertex[0].z, f->vertex[1].z), f->vertex[2].z),
std::max(std::max(f->vertex[0].z, f->vertex[1].z), f->vertex[2].z));
std::min(std::min(f->vertex[0](2), f->vertex[1](2)), f->vertex[2](2)),
std::max(std::max(f->vertex[0](2), f->vertex[1](2)), f->vertex[2](2)));
}
void SlicingAdaptive::prepare()
@ -40,7 +40,7 @@ void SlicingAdaptive::prepare()
// 3) Generate Z components of the facet normals.
m_face_normal_z.assign(m_faces.size(), 0.f);
for (size_t iface = 0; iface < m_faces.size(); ++ iface)
m_face_normal_z[iface] = m_faces[iface]->normal.z;
m_face_normal_z[iface] = m_faces[iface]->normal(2);
}
float SlicingAdaptive::cusp_height(float z, float cusp_value, int &current_facet)

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);
}