diff --git a/src/admesh/connect.cpp b/src/admesh/connect.cpp index 1a7b7965d..5afb85d2c 100644 --- a/src/admesh/connect.cpp +++ b/src/admesh/connect.cpp @@ -30,6 +30,8 @@ #include #include +// Boost pool: Don't use mutexes to synchronize memory allocation. +#define BOOST_POOL_NO_MT #include #include "stl.h" diff --git a/src/admesh/stl.h b/src/admesh/stl.h index 40bced2f4..87210b3c9 100644 --- a/src/admesh/stl.h +++ b/src/admesh/stl.h @@ -89,6 +89,8 @@ struct stl_neighbors { }; struct stl_stats { + stl_stats() { this->reset(); } + void reset() { memset(this, 0, sizeof(stl_stats)); this->volume = -1.0; } char header[81]; stl_type type; uint32_t number_of_facets; @@ -117,6 +119,18 @@ struct stl_stats { }; struct stl_file { + stl_file() {} + stl_file(const stl_file &rhs) : facet_start(rhs.facet_start), neighbors_start(rhs.neighbors_start), stats(rhs.stats) {} + stl_file(stl_file &&rhs) : facet_start(std::move(rhs.facet_start)), neighbors_start(std::move(rhs.neighbors_start)), stats(rhs.stats) {} + stl_file& operator=(const stl_file &rhs) { this->facet_start = rhs.facet_start; this->neighbors_start = rhs.neighbors_start; this->stats = rhs.stats; return *this; } + stl_file& operator=(stl_file &&rhs) { this->facet_start = std::move(rhs.facet_start); this->neighbors_start = std::move(rhs.neighbors_start); this->stats = rhs.stats; return *this; } + + void clear() { + this->facet_start.clear(); + this->neighbors_start.clear(); + this->stats.reset(); + } + std::vector facet_start; std::vector neighbors_start; // Statistics @@ -125,7 +139,14 @@ struct stl_file { struct indexed_triangle_set { + indexed_triangle_set() {} + indexed_triangle_set(const indexed_triangle_set &rhs) : indices(rhs.indices), vertices(rhs.vertices) {} + indexed_triangle_set(indexed_triangle_set &&rhs) : indices(std::move(rhs.indices)), vertices(std::move(rhs.vertices)) {} + indexed_triangle_set& operator=(const indexed_triangle_set &rhs) { this->indices = rhs.indices; this->vertices = rhs.vertices; return *this; } + indexed_triangle_set& operator=(indexed_triangle_set &&rhs) { this->indices = std::move(rhs.indices); this->vertices = std::move(rhs.vertices); return *this; } + void clear() { indices.clear(); vertices.clear(); } + std::vector indices; std::vector vertices; //FIXME add normals once we get rid of the stl_file from TriangleMesh completely. @@ -238,6 +259,10 @@ inline void its_transform(indexed_triangle_set &its, const Eigen::Matrix()).template cast().eval(); } +extern void its_rotate_x(indexed_triangle_set &its, float angle); +extern void its_rotate_y(indexed_triangle_set &its, float angle); +extern void its_rotate_z(indexed_triangle_set &its, float angle); + extern void stl_generate_shared_vertices(stl_file *stl, indexed_triangle_set &its); extern bool its_write_obj(const indexed_triangle_set &its, const char *file); extern bool its_write_off(const indexed_triangle_set &its, const char *file); @@ -258,7 +283,6 @@ extern void stl_calculate_volume(stl_file *stl); 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_allocate(stl_file *stl); extern void stl_read(stl_file *stl, int first_facet, bool first); extern void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first); diff --git a/src/admesh/stlinit.cpp b/src/admesh/stlinit.cpp index 0cc6e50c7..a328baa75 100644 --- a/src/admesh/stlinit.cpp +++ b/src/admesh/stlinit.cpp @@ -221,7 +221,7 @@ static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first) bool stl_open(stl_file *stl, const char *file) { - stl_reset(stl); + stl->clear(); FILE *fp = stl_open_count_facets(stl, file); if (fp == nullptr) return false; @@ -231,14 +231,6 @@ bool stl_open(stl_file *stl, const char *file) return result; } -void stl_reset(stl_file *stl) -{ - stl->facet_start.clear(); - stl->neighbors_start.clear(); - memset(&stl->stats, 0, sizeof(stl_stats)); - stl->stats.volume = -1.0; -} - #ifndef BOOST_LITTLE_ENDIAN extern void stl_internal_reverse_quads(char *buf, size_t cnt); #endif /* BOOST_LITTLE_ENDIAN */ diff --git a/src/admesh/util.cpp b/src/admesh/util.cpp index 70f4ffc27..029e44a28 100644 --- a/src/admesh/util.cpp +++ b/src/admesh/util.cpp @@ -115,12 +115,12 @@ static void calculate_normals(stl_file *stl) } } -static void rotate_point_2d(float *x, float *y, const double c, const double s) +static inline void rotate_point_2d(float &x, float &y, const double c, const double s) { - double xold = *x; - double yold = *y; - *x = float(c * xold - s * yold); - *y = float(s * xold + c * yold); + double xold = x; + double yold = y; + x = float(c * xold - s * yold); + y = float(s * xold + c * yold); } void stl_rotate_x(stl_file *stl, float angle) @@ -130,7 +130,7 @@ void stl_rotate_x(stl_file *stl, float angle) double s = sin(radian_angle); for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) for (int j = 0; j < 3; ++ j) - rotate_point_2d(&stl->facet_start[i].vertex[j](1), &stl->facet_start[i].vertex[j](2), c, s); + rotate_point_2d(stl->facet_start[i].vertex[j](1), stl->facet_start[i].vertex[j](2), c, s); stl_get_size(stl); calculate_normals(stl); } @@ -142,7 +142,7 @@ void stl_rotate_y(stl_file *stl, float angle) double s = sin(radian_angle); for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) for (int j = 0; j < 3; ++ j) - rotate_point_2d(&stl->facet_start[i].vertex[j](2), &stl->facet_start[i].vertex[j](0), c, s); + rotate_point_2d(stl->facet_start[i].vertex[j](2), stl->facet_start[i].vertex[j](0), c, s); stl_get_size(stl); calculate_normals(stl); } @@ -154,11 +154,38 @@ void stl_rotate_z(stl_file *stl, float angle) double s = sin(radian_angle); for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) for (int j = 0; j < 3; ++ j) - rotate_point_2d(&stl->facet_start[i].vertex[j](0), &stl->facet_start[i].vertex[j](1), c, s); + rotate_point_2d(stl->facet_start[i].vertex[j](0), stl->facet_start[i].vertex[j](1), c, s); stl_get_size(stl); calculate_normals(stl); } +void its_rotate_x(indexed_triangle_set &its, float angle) +{ + double radian_angle = (angle / 180.0) * M_PI; + double c = cos(radian_angle); + double s = sin(radian_angle); + for (stl_vertex &v : its.vertices) + rotate_point_2d(v(1), v(2), c, s); +} + +void its_rotate_y(indexed_triangle_set& its, float angle) +{ + double radian_angle = (angle / 180.0) * M_PI; + double c = cos(radian_angle); + double s = sin(radian_angle); + for (stl_vertex& v : its.vertices) + rotate_point_2d(v(2), v(0), c, s); +} + +void its_rotate_z(indexed_triangle_set& its, float angle) +{ + double radian_angle = (angle / 180.0) * M_PI; + double c = cos(radian_angle); + double s = sin(radian_angle); + for (stl_vertex& v : its.vertices) + rotate_point_2d(v(0), v(1), c, s); +} + void stl_get_size(stl_file *stl) { if (stl->stats.number_of_facets == 0) diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index 11f45147c..56accfefa 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -42,10 +42,8 @@ namespace Slic3r { -TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector& facets) - : repaired(false) +TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector& facets) : repaired(false) { - stl_reset(&this->stl); stl_file &stl = this->stl; stl.stats.type = inmemory; @@ -72,14 +70,6 @@ TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector& f stl_get_size(&stl); } -TriangleMesh& TriangleMesh::operator=(const TriangleMesh &other) -{ - stl_reset(&this->stl); - this->stl = other.stl; - this->repaired = other.repaired; - return *this; -} - // #define SLIC3R_TRACE_REPAIR void TriangleMesh::repair(bool update_shared_vertices) @@ -254,13 +244,18 @@ void TriangleMesh::WriteOBJFile(const char* output_file) void TriangleMesh::scale(float factor) { stl_scale(&(this->stl), factor); - this->its.clear(); + for (stl_vertex& v : this->its.vertices) + v *= factor; } void TriangleMesh::scale(const Vec3d &versor) { stl_scale_versor(&this->stl, versor.cast()); - this->its.clear(); + for (stl_vertex& v : this->its.vertices) { + v.x() *= versor.x(); + v.y() *= versor.y(); + v.z() *= versor.z(); + } } void TriangleMesh::translate(float x, float y, float z) @@ -268,7 +263,9 @@ void TriangleMesh::translate(float x, float y, float z) if (x == 0.f && y == 0.f && z == 0.f) return; stl_translate_relative(&(this->stl), x, y, z); - this->its.clear(); + stl_vertex shift(x, y, z); + for (stl_vertex& v : this->its.vertices) + v += shift; } void TriangleMesh::translate(const Vec3f &displacement) @@ -285,13 +282,15 @@ void TriangleMesh::rotate(float angle, const Axis &axis) angle = Slic3r::Geometry::rad2deg(angle); if (axis == X) { - stl_rotate_x(&(this->stl), angle); + stl_rotate_x(&this->stl, angle); + its_rotate_x(this->its, angle); } else if (axis == Y) { - stl_rotate_y(&(this->stl), angle); + stl_rotate_y(&this->stl, angle); + its_rotate_y(this->its, angle); } else if (axis == Z) { - stl_rotate_z(&(this->stl), angle); + stl_rotate_z(&this->stl, angle); + its_rotate_z(this->its, angle); } - this->its.clear(); } void TriangleMesh::rotate(float angle, const Vec3d& axis) @@ -310,12 +309,17 @@ void TriangleMesh::mirror(const Axis &axis) { if (axis == X) { stl_mirror_yz(&this->stl); + for (stl_vertex &v : this->its.vertices) + v(0) *= -1.0; } else if (axis == Y) { stl_mirror_xz(&this->stl); + for (stl_vertex &v : this->its.vertices) + v(1) *= -1.0; } else if (axis == Z) { stl_mirror_xy(&this->stl); + for (stl_vertex &v : this->its.vertices) + v(2) *= -1.0; } - this->its.clear(); } void TriangleMesh::transform(const Transform3d& t, bool fix_left_handed) @@ -358,7 +362,8 @@ void TriangleMesh::rotate(double angle, Point* center) return; Vec2f c = center->cast(); this->translate(-c(0), -c(1), 0); - stl_rotate_z(&(this->stl), (float)angle); + stl_rotate_z(&this->stl, (float)angle); + its_rotate_z(this->its, (float)angle); this->translate(c(0), c(1), 0); } @@ -540,7 +545,7 @@ TriangleMesh TriangleMesh::convex_hull_3d() const { if (this->has_shared_vertices()) { #if REALfloat - qhull.runQhull("", 3, (int)this->its.vertices.size() / 3, (const realT*)(this->its.vertices.front().data()), "Qt"); + qhull.runQhull("", 3, (int)this->its.vertices.size(), (const realT*)(this->its.vertices.front().data()), "Qt"); #else src_vertices.reserve(this->its.vertices() * 3); // We will now fill the vector with input points for computation: diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index ffd9b7e62..54c6dc5d0 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -21,15 +21,13 @@ typedef std::vector TriangleMeshPtrs; class TriangleMesh { public: - TriangleMesh() : repaired(false) { stl_reset(&this->stl); } + TriangleMesh() : repaired(false) {} TriangleMesh(const Pointf3s &points, const std::vector &facets); - TriangleMesh(const TriangleMesh &other) : repaired(false) { stl_reset(&this->stl); *this = other; } - TriangleMesh(TriangleMesh &&other) : repaired(false) { stl_reset(&this->stl); this->swap(other); } - ~TriangleMesh() { clear(); } - TriangleMesh& operator=(const TriangleMesh &other); - TriangleMesh& operator=(TriangleMesh &&other) { this->swap(other); return *this; } - void clear() { stl_reset(&this->stl); this->repaired = false; } - void swap(TriangleMesh &other) { std::swap(this->stl, other.stl); std::swap(this->repaired, other.repaired); } + TriangleMesh(const TriangleMesh& rhs) : stl(rhs.stl), its(rhs.its), repaired(rhs.repaired) {} + TriangleMesh(TriangleMesh&& rhs) : stl(std::move(rhs.stl)), its(std::move(rhs.its)), repaired(rhs.repaired) {} + TriangleMesh& operator=(const TriangleMesh& rhs) { this->stl = rhs.stl; this->its = rhs.its; this->repaired = rhs.repaired; return *this; } + TriangleMesh& operator=(TriangleMesh &&rhs) { this->stl = std::move(rhs.stl); this->its = std::move(rhs.its); this->repaired = rhs.repaired; return *this; } + void clear() { this->stl.clear(); this->its.clear(); this->repaired = false; } bool ReadSTLFile(const char* input_file) { return stl_open(&stl, input_file); } bool write_ascii(const char* output_file) { return stl_write_ascii(&this->stl, output_file, ""); } bool write_binary(const char* output_file) { return stl_write_binary(&this->stl, output_file, ""); } diff --git a/src/slic3r/Config/Version.cpp b/src/slic3r/Config/Version.cpp index 2eda135d6..fe3adfd7f 100644 --- a/src/slic3r/Config/Version.cpp +++ b/src/slic3r/Config/Version.cpp @@ -198,6 +198,11 @@ size_t Index::load(const boost::filesystem::path &path) size_t idx_line = 0; Version ver; while (std::getline(ifs, line)) { +#ifndef _MSVCVER + // On a Unix system, getline does not remove the trailing carriage returns, if the index is shared over a Windows filesystem. Remove them manually. + while (! line.empty() && line.back() == '\r') + line.pop_back(); +#endif ++ idx_line; // Skip the initial white spaces. char *key = left_trim(const_cast(line.data())); diff --git a/src/slic3r/Utils/FixModelByWin10.cpp b/src/slic3r/Utils/FixModelByWin10.cpp index 1daeaff26..710f19090 100644 --- a/src/slic3r/Utils/FixModelByWin10.cpp +++ b/src/slic3r/Utils/FixModelByWin10.cpp @@ -389,10 +389,10 @@ void fix_model_by_win10_sdk_gui(ModelObject &model_object, int volume_idx) throw std::runtime_error(L("Repaired 3MF file does not contain any volume")); if (model.objects.front()->volumes.size() > 1) throw std::runtime_error(L("Repaired 3MF file contains more than one volume")); - meshes_repaired.emplace_back(std::move(model.objects.front()->volumes.front()->mesh)); + meshes_repaired.emplace_back(std::move(model.objects.front()->volumes.front()->mesh())); } for (size_t i = 0; i < volumes.size(); ++ i) { - volumes[i]->mesh = std::move(meshes_repaired[i]); + volumes[i]->set_mesh(std::move(meshes_repaired[i])); volumes[i]->set_new_unique_id(); } model_object.invalidate_bounding_box();