Merge branch 'master' into fs_emboss
This commit is contained in:
commit
a78122bce7
11 changed files with 1850 additions and 1777 deletions
|
@ -83,6 +83,13 @@ public:
|
||||||
// to split around.
|
// to split around.
|
||||||
template<typename SourceNode>
|
template<typename SourceNode>
|
||||||
void build(std::vector<SourceNode> &&input)
|
void build(std::vector<SourceNode> &&input)
|
||||||
|
{
|
||||||
|
this->build_modify_input(input);
|
||||||
|
input.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename SourceNode>
|
||||||
|
void build_modify_input(std::vector<SourceNode> &input)
|
||||||
{
|
{
|
||||||
if (input.empty())
|
if (input.empty())
|
||||||
clear();
|
clear();
|
||||||
|
@ -91,7 +98,6 @@ public:
|
||||||
m_nodes.assign(next_highest_power_of_2(input.size()) * 2 - 1, Node());
|
m_nodes.assign(next_highest_power_of_2(input.size()) * 2 - 1, Node());
|
||||||
build_recursive(input, 0, 0, input.size() - 1);
|
build_recursive(input, 0, 0, input.size() - 1);
|
||||||
}
|
}
|
||||||
input.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Node>& nodes() const { return m_nodes; }
|
const std::vector<Node>& nodes() const { return m_nodes; }
|
||||||
|
|
|
@ -1769,7 +1769,7 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line, bool
|
||||||
switch (cmd[1]) {
|
switch (cmd[1]) {
|
||||||
case '1':
|
case '1':
|
||||||
switch (cmd[2]) {
|
switch (cmd[2]) {
|
||||||
case '0': { process_G10(line); break; } // Retract
|
case '0': { process_G10(line); break; } // Retract or Set tool temperature
|
||||||
case '1': { process_G11(line); break; } // Unretract
|
case '1': { process_G11(line); break; } // Unretract
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
@ -3232,6 +3232,23 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc
|
||||||
|
|
||||||
void GCodeProcessor::process_G10(const GCodeReader::GCodeLine& line)
|
void GCodeProcessor::process_G10(const GCodeReader::GCodeLine& line)
|
||||||
{
|
{
|
||||||
|
if (m_flavor == gcfRepRapFirmware) {
|
||||||
|
// similar to M104/M109
|
||||||
|
float new_temp;
|
||||||
|
if (line.has_value('S', new_temp)) {
|
||||||
|
size_t id = m_extruder_id;
|
||||||
|
float val;
|
||||||
|
if (line.has_value('P', val)) {
|
||||||
|
const size_t eid = static_cast<size_t>(val);
|
||||||
|
if (eid < m_extruder_temps.size())
|
||||||
|
id = eid;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_extruder_temps[id] = new_temp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// stores retract move
|
// stores retract move
|
||||||
store_move_vertex(EMoveType::Retract);
|
store_move_vertex(EMoveType::Retract);
|
||||||
}
|
}
|
||||||
|
@ -3441,18 +3458,22 @@ void GCodeProcessor::process_M108(const GCodeReader::GCodeLine& line)
|
||||||
void GCodeProcessor::process_M109(const GCodeReader::GCodeLine& line)
|
void GCodeProcessor::process_M109(const GCodeReader::GCodeLine& line)
|
||||||
{
|
{
|
||||||
float new_temp;
|
float new_temp;
|
||||||
|
size_t id = (size_t)-1;
|
||||||
if (line.has_value('R', new_temp)) {
|
if (line.has_value('R', new_temp)) {
|
||||||
float val;
|
float val;
|
||||||
if (line.has_value('T', val)) {
|
if (line.has_value('T', val)) {
|
||||||
const size_t eid = static_cast<size_t>(val);
|
const size_t eid = static_cast<size_t>(val);
|
||||||
if (eid < m_extruder_temps.size())
|
if (eid < m_extruder_temps.size())
|
||||||
m_extruder_temps[eid] = new_temp;
|
id = eid;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_extruder_temps[m_extruder_id] = new_temp;
|
id = m_extruder_id;
|
||||||
}
|
}
|
||||||
else if (line.has_value('S', new_temp))
|
else if (line.has_value('S', new_temp))
|
||||||
m_extruder_temps[m_extruder_id] = new_temp;
|
id = m_extruder_id;
|
||||||
|
|
||||||
|
if (id != (size_t)-1)
|
||||||
|
m_extruder_temps[id] = new_temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeProcessor::process_M132(const GCodeReader::GCodeLine& line)
|
void GCodeProcessor::process_M132(const GCodeReader::GCodeLine& line)
|
||||||
|
|
|
@ -674,7 +674,7 @@ namespace Slic3r {
|
||||||
void process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise);
|
void process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise);
|
||||||
#endif // ENABLE_PROCESS_G2_G3_LINES
|
#endif // ENABLE_PROCESS_G2_G3_LINES
|
||||||
|
|
||||||
// Retract
|
// Retract or Set tool temperature
|
||||||
void process_G10(const GCodeReader::GCodeLine& line);
|
void process_G10(const GCodeReader::GCodeLine& line);
|
||||||
|
|
||||||
// Unretract
|
// Unretract
|
||||||
|
|
|
@ -1359,7 +1359,7 @@ void ModelObject::split(ModelObjectPtrs* new_objects)
|
||||||
size_t counter = 1;
|
size_t counter = 1;
|
||||||
for (TriangleMesh &mesh : meshes) {
|
for (TriangleMesh &mesh : meshes) {
|
||||||
// FIXME: crashes if not satisfied
|
// FIXME: crashes if not satisfied
|
||||||
if (mesh.facets_count() < 3)
|
if (mesh.facets_count() < 3 || mesh.has_zero_volume())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// XXX: this seems to be the only real usage of m_model, maybe refactor this so that it's not needed?
|
// XXX: this seems to be the only real usage of m_model, maybe refactor this so that it's not needed?
|
||||||
|
@ -1833,7 +1833,7 @@ size_t ModelVolume::split(unsigned int max_extruders)
|
||||||
const Vec3d offset = this->get_offset();
|
const Vec3d offset = this->get_offset();
|
||||||
|
|
||||||
for (TriangleMesh &mesh : meshes) {
|
for (TriangleMesh &mesh : meshes) {
|
||||||
if (mesh.empty())
|
if (mesh.empty() || mesh.has_zero_volume())
|
||||||
// Repair may have removed unconnected triangles, thus emptying the mesh.
|
// Repair may have removed unconnected triangles, thus emptying the mesh.
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -2198,8 +2198,7 @@ void PrintObject::combine_infill()
|
||||||
void PrintObject::_generate_support_material()
|
void PrintObject::_generate_support_material()
|
||||||
{
|
{
|
||||||
if (m_config.support_material_style == smsTree) {
|
if (m_config.support_material_style == smsTree) {
|
||||||
TreeSupport tree_support;
|
fff_tree_support_generate(*this, std::function<void()>([this](){ this->throw_if_canceled(); }));
|
||||||
tree_support.generateSupportAreas(*this);
|
|
||||||
} else {
|
} else {
|
||||||
PrintObjectSupportMaterial support_material(this, m_slicing_params);
|
PrintObjectSupportMaterial support_material(this, m_slicing_params);
|
||||||
support_material.generate(*this);
|
support_material.generate(*this);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
#include <tbb/task_group.h>
|
#include <tbb/task_group.h>
|
||||||
|
|
||||||
namespace Slic3r
|
namespace Slic3r::FFFTreeSupport
|
||||||
{
|
{
|
||||||
|
|
||||||
// or warning
|
// or warning
|
||||||
|
@ -106,7 +106,10 @@ TreeModelVolumes::TreeModelVolumes(
|
||||||
const PrintObject &print_object,
|
const PrintObject &print_object,
|
||||||
const BuildVolume &build_volume,
|
const BuildVolume &build_volume,
|
||||||
const coord_t max_move, const coord_t max_move_slow, size_t current_mesh_idx,
|
const coord_t max_move, const coord_t max_move_slow, size_t current_mesh_idx,
|
||||||
double progress_multiplier, double progress_offset, const std::vector<Polygons>& additional_excluded_areas) :
|
#ifdef SLIC3R_TREESUPPORTS_PROGRESS
|
||||||
|
double progress_multiplier, double progress_offset,
|
||||||
|
#endif // SLIC3R_TREESUPPORTS_PROGRESS
|
||||||
|
const std::vector<Polygons>& additional_excluded_areas) :
|
||||||
// -2 to avoid rounding errors
|
// -2 to avoid rounding errors
|
||||||
m_max_move{ std::max<coord_t>(max_move - 2, 0) }, m_max_move_slow{ std::max<coord_t>(max_move_slow - 2, 0) },
|
m_max_move{ std::max<coord_t>(max_move - 2, 0) }, m_max_move_slow{ std::max<coord_t>(max_move_slow - 2, 0) },
|
||||||
#ifdef SLIC3R_TREESUPPORTS_PROGRESS
|
#ifdef SLIC3R_TREESUPPORTS_PROGRESS
|
||||||
|
@ -161,7 +164,7 @@ TreeModelVolumes::TreeModelVolumes(
|
||||||
m_min_resolution = std::min(m_min_resolution, data_pair.first.resolution);
|
m_min_resolution = std::min(m_min_resolution, data_pair.first.resolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TreeSupport::TreeSupportSettings config{ m_layer_outlines[m_current_outline_idx].first };
|
const TreeSupportSettings config{ m_layer_outlines[m_current_outline_idx].first };
|
||||||
m_current_min_xy_dist = config.xy_min_distance;
|
m_current_min_xy_dist = config.xy_min_distance;
|
||||||
m_current_min_xy_dist_delta = config.xy_distance - m_current_min_xy_dist;
|
m_current_min_xy_dist_delta = config.xy_distance - m_current_min_xy_dist;
|
||||||
assert(m_current_min_xy_dist_delta >= 0);
|
assert(m_current_min_xy_dist_delta >= 0);
|
||||||
|
@ -206,7 +209,7 @@ void TreeModelVolumes::precalculate(const coord_t max_layer)
|
||||||
// Get the config corresponding to one mesh that is in the current group. Which one has to be irrelevant.
|
// Get the config corresponding to one mesh that is in the current group. Which one has to be irrelevant.
|
||||||
// Not the prettiest way to do this, but it ensures some calculations that may be a bit more complex
|
// Not the prettiest way to do this, but it ensures some calculations that may be a bit more complex
|
||||||
// like inital layer diameter are only done in once.
|
// like inital layer diameter are only done in once.
|
||||||
TreeSupport::TreeSupportSettings config(m_layer_outlines[m_current_outline_idx].first);
|
TreeSupportSettings config(m_layer_outlines[m_current_outline_idx].first);
|
||||||
|
|
||||||
{
|
{
|
||||||
// calculate which radius each layer in the tip may have.
|
// calculate which radius each layer in the tip may have.
|
||||||
|
@ -297,7 +300,7 @@ const Polygons& TreeModelVolumes::getCollision(const coord_t orig_radius, LayerI
|
||||||
return (*result).get();
|
return (*result).get();
|
||||||
if (m_precalculated) {
|
if (m_precalculated) {
|
||||||
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate collision at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate collision at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
||||||
TreeSupport::showError("Not precalculated Collision requested.", false);
|
tree_supports_show_error("Not precalculated Collision requested.", false);
|
||||||
}
|
}
|
||||||
const_cast<TreeModelVolumes*>(this)->calculateCollision(radius, layer_idx);
|
const_cast<TreeModelVolumes*>(this)->calculateCollision(radius, layer_idx);
|
||||||
return getCollision(orig_radius, layer_idx, min_xy_dist);
|
return getCollision(orig_radius, layer_idx, min_xy_dist);
|
||||||
|
@ -312,7 +315,7 @@ const Polygons& TreeModelVolumes::getCollisionHolefree(coord_t radius, LayerInde
|
||||||
return (*result).get();
|
return (*result).get();
|
||||||
if (m_precalculated) {
|
if (m_precalculated) {
|
||||||
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate collision holefree at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate collision holefree at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
||||||
TreeSupport::showError("Not precalculated Holefree Collision requested.", false);
|
tree_supports_show_error("Not precalculated Holefree Collision requested.", false);
|
||||||
}
|
}
|
||||||
const_cast<TreeModelVolumes*>(this)->calculateCollisionHolefree({ radius, layer_idx });
|
const_cast<TreeModelVolumes*>(this)->calculateCollisionHolefree({ radius, layer_idx });
|
||||||
return getCollisionHolefree(radius, layer_idx);
|
return getCollisionHolefree(radius, layer_idx);
|
||||||
|
@ -336,10 +339,10 @@ const Polygons& TreeModelVolumes::getAvoidance(const coord_t orig_radius, LayerI
|
||||||
if (m_precalculated) {
|
if (m_precalculated) {
|
||||||
if (to_model) {
|
if (to_model) {
|
||||||
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate Avoidance to model at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate Avoidance to model at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
||||||
TreeSupport::showError("Not precalculated Avoidance(to model) requested.", false);
|
tree_supports_show_error("Not precalculated Avoidance(to model) requested.", false);
|
||||||
} else {
|
} else {
|
||||||
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate Avoidance at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate Avoidance at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
||||||
TreeSupport::showError("Not precalculated Avoidance(to buildplate) requested.", false);
|
tree_supports_show_error("Not precalculated Avoidance(to buildplate) requested.", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const_cast<TreeModelVolumes*>(this)->calculateAvoidance({ radius, layer_idx }, ! to_model, to_model);
|
const_cast<TreeModelVolumes*>(this)->calculateAvoidance({ radius, layer_idx }, ! to_model, to_model);
|
||||||
|
@ -357,7 +360,7 @@ const Polygons& TreeModelVolumes::getPlaceableAreas(const coord_t orig_radius, L
|
||||||
return (*result).get();
|
return (*result).get();
|
||||||
if (m_precalculated) {
|
if (m_precalculated) {
|
||||||
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate Placeable Areas at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate Placeable Areas at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
||||||
TreeSupport::showError("Not precalculated Placeable areas requested.", false);
|
tree_supports_show_error("Not precalculated Placeable areas requested.", false);
|
||||||
}
|
}
|
||||||
const_cast<TreeModelVolumes*>(this)->calculatePlaceables(radius, layer_idx);
|
const_cast<TreeModelVolumes*>(this)->calculatePlaceables(radius, layer_idx);
|
||||||
return getPlaceableAreas(orig_radius, layer_idx);
|
return getPlaceableAreas(orig_radius, layer_idx);
|
||||||
|
@ -380,7 +383,7 @@ const Polygons& TreeModelVolumes::getWallRestriction(const coord_t orig_radius,
|
||||||
return (*result).get();
|
return (*result).get();
|
||||||
if (m_precalculated) {
|
if (m_precalculated) {
|
||||||
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate Wall restricions at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate Wall restricions at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
||||||
TreeSupport::showError(
|
tree_supports_show_error(
|
||||||
min_xy_dist ?
|
min_xy_dist ?
|
||||||
"Not precalculated Wall restriction of minimum xy distance requested )." :
|
"Not precalculated Wall restriction of minimum xy distance requested )." :
|
||||||
"Not precalculated Wall restriction requested )."
|
"Not precalculated Wall restriction requested )."
|
||||||
|
@ -774,4 +777,4 @@ coord_t TreeModelVolumes::ceilRadius(const coord_t radius) const
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace Slic3r::FFFTreeSupport
|
||||||
|
|
|
@ -22,11 +22,14 @@
|
||||||
namespace Slic3r
|
namespace Slic3r
|
||||||
{
|
{
|
||||||
|
|
||||||
using LayerIndex = int;
|
|
||||||
|
|
||||||
class BuildVolume;
|
class BuildVolume;
|
||||||
class PrintObject;
|
class PrintObject;
|
||||||
|
|
||||||
|
namespace FFFTreeSupport
|
||||||
|
{
|
||||||
|
|
||||||
|
using LayerIndex = int;
|
||||||
|
|
||||||
struct TreeSupportMeshGroupSettings {
|
struct TreeSupportMeshGroupSettings {
|
||||||
TreeSupportMeshGroupSettings() = default;
|
TreeSupportMeshGroupSettings() = default;
|
||||||
explicit TreeSupportMeshGroupSettings(const PrintObject &print_object);
|
explicit TreeSupportMeshGroupSettings(const PrintObject &print_object);
|
||||||
|
@ -194,15 +197,19 @@ class TreeModelVolumes
|
||||||
public:
|
public:
|
||||||
TreeModelVolumes() = default;
|
TreeModelVolumes() = default;
|
||||||
explicit TreeModelVolumes(const PrintObject &print_object, const BuildVolume &build_volume,
|
explicit TreeModelVolumes(const PrintObject &print_object, const BuildVolume &build_volume,
|
||||||
coord_t max_move, coord_t max_move_slow, size_t current_mesh_idx, double progress_multiplier,
|
coord_t max_move, coord_t max_move_slow, size_t current_mesh_idx,
|
||||||
double progress_offset, const std::vector<Polygons> &additional_excluded_areas = {});
|
#ifdef SLIC3R_TREESUPPORTS_PROGRESS
|
||||||
|
double progress_multiplier,
|
||||||
|
double progress_offset,
|
||||||
|
#endif // SLIC3R_TREESUPPORTS_PROGRESS
|
||||||
|
const std::vector<Polygons> &additional_excluded_areas = {});
|
||||||
TreeModelVolumes(TreeModelVolumes&&) = default;
|
TreeModelVolumes(TreeModelVolumes&&) = default;
|
||||||
TreeModelVolumes& operator=(TreeModelVolumes&&) = default;
|
TreeModelVolumes& operator=(TreeModelVolumes&&) = default;
|
||||||
|
|
||||||
TreeModelVolumes(const TreeModelVolumes&) = delete;
|
TreeModelVolumes(const TreeModelVolumes&) = delete;
|
||||||
TreeModelVolumes& operator=(const TreeModelVolumes&) = delete;
|
TreeModelVolumes& operator=(const TreeModelVolumes&) = delete;
|
||||||
|
|
||||||
enum class AvoidanceType
|
enum class AvoidanceType : int8_t
|
||||||
{
|
{
|
||||||
Slow,
|
Slow,
|
||||||
FastSafe,
|
FastSafe,
|
||||||
|
@ -605,6 +612,7 @@ private:
|
||||||
#endif // SLIC3R_TREESUPPORTS_PROGRESS
|
#endif // SLIC3R_TREESUPPORTS_PROGRESS
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace FFFTreeSupport
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
#endif //slic3r_TreeModelVolumes_hpp
|
#endif //slic3r_TreeModelVolumes_hpp
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -378,6 +378,14 @@ bool TriangleMesh::is_splittable() const
|
||||||
return its_is_splittable(this->its);
|
return its_is_splittable(this->its);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TriangleMesh::has_zero_volume() const
|
||||||
|
{
|
||||||
|
const Vec3d sz = size();
|
||||||
|
const double volume_val = sz.x() * sz.y() * sz.z();
|
||||||
|
|
||||||
|
return is_approx(volume_val, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<TriangleMesh> TriangleMesh::split() const
|
std::vector<TriangleMesh> TriangleMesh::split() const
|
||||||
{
|
{
|
||||||
std::vector<indexed_triangle_set> itss = its_split(this->its);
|
std::vector<indexed_triangle_set> itss = its_split(this->its);
|
||||||
|
|
|
@ -139,6 +139,7 @@ public:
|
||||||
bool empty() const { return this->facets_count() == 0; }
|
bool empty() const { return this->facets_count() == 0; }
|
||||||
bool repaired() const;
|
bool repaired() const;
|
||||||
bool is_splittable() const;
|
bool is_splittable() const;
|
||||||
|
bool has_zero_volume() const;
|
||||||
// Estimate of the memory occupied by this structure, important for keeping an eye on the Undo / Redo stack allocation.
|
// Estimate of the memory occupied by this structure, important for keeping an eye on the Undo / Redo stack allocation.
|
||||||
size_t memsize() const;
|
size_t memsize() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue