mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-07 12:49:10 +08:00
Porting supports_z funtion.
This commit is contained in:
parent
7ff2f17382
commit
5546d28150
@ -422,11 +422,12 @@ sub support_layers_z {
|
|||||||
# add raft layers by dividing the space between first layer and
|
# add raft layers by dividing the space between first layer and
|
||||||
# first contact layer evenly
|
# first contact layer evenly
|
||||||
if ($self->object_config->raft_layers > 1 && @z >= 2) {
|
if ($self->object_config->raft_layers > 1 && @z >= 2) {
|
||||||
|
print @z;
|
||||||
# $z[1] is last raft layer (contact layer for the first layer object)
|
# $z[1] is last raft layer (contact layer for the first layer object)
|
||||||
my $height = ($z[1] - $z[0]) / ($self->object_config->raft_layers - 1);
|
my $height = ($z[1] - $z[0]) / ($self->object_config->raft_layers - 1);
|
||||||
# since we already have two raft layers ($z[0] and $z[1]) we need to insert
|
# since we already have two raft layers ($z[0] and $z[1]) we need to insert
|
||||||
# raft_layers-2 more
|
# raft_layers-2 more
|
||||||
splice @z, 1, 0,
|
splice @z, 1, 0, #splice ARRAY,OFFSET,LENGTH,LIST
|
||||||
map { sprintf "%.2f", $_ }
|
map { sprintf "%.2f", $_ }
|
||||||
map { $z[0] + $height * $_ }
|
map { $z[0] + $height * $_ }
|
||||||
1..($self->object_config->raft_layers - 2);
|
1..($self->object_config->raft_layers - 2);
|
||||||
@ -450,6 +451,7 @@ sub support_layers_z {
|
|||||||
# remove duplicates and make sure all 0.x values have the leading 0
|
# remove duplicates and make sure all 0.x values have the leading 0
|
||||||
{
|
{
|
||||||
my %sl = map { 1 * $_ => 1 } @z;
|
my %sl = map { 1 * $_ => 1 } @z;
|
||||||
|
print "HERE";
|
||||||
@z = sort { $a <=> $b } keys %sl;
|
@z = sort { $a <=> $b } keys %sl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ add_library(libslic3r STATIC
|
|||||||
${LIBDIR}/libslic3r/SVG.cpp
|
${LIBDIR}/libslic3r/SVG.cpp
|
||||||
${LIBDIR}/libslic3r/TriangleMesh.cpp
|
${LIBDIR}/libslic3r/TriangleMesh.cpp
|
||||||
${LIBDIR}/libslic3r/Zip/ZipArchive.cpp
|
${LIBDIR}/libslic3r/Zip/ZipArchive.cpp
|
||||||
)
|
../xs/src/libslic3r/SupportMaterial.cpp)
|
||||||
|
|
||||||
add_library(BSpline STATIC
|
add_library(BSpline STATIC
|
||||||
${LIBDIR}/BSpline/BSpline.cpp
|
${LIBDIR}/BSpline/BSpline.cpp
|
||||||
|
1
xs/src/libslic3r/SupportMaterial.cpp
Normal file
1
xs/src/libslic3r/SupportMaterial.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "SupportMaterial.hpp"
|
@ -2,6 +2,8 @@
|
|||||||
#define slic3r_SupportMaterial_hpp_
|
#define slic3r_SupportMaterial_hpp_
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
#include "libslic3r.h"
|
#include "libslic3r.h"
|
||||||
#include "PrintConfig.hpp"
|
#include "PrintConfig.hpp"
|
||||||
#include "Flow.hpp"
|
#include "Flow.hpp"
|
||||||
@ -14,31 +16,32 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#define MARGIN_STEP MARGIN/3
|
namespace Slic3r
|
||||||
#define PILLAR_SIZE 2.5
|
{
|
||||||
#define PILLAR_SPACING 10
|
|
||||||
|
|
||||||
namespace Slic3r {
|
|
||||||
|
|
||||||
// how much we extend support around the actual contact area
|
// how much we extend support around the actual contact area
|
||||||
constexpr coordf_t SUPPORT_MATERIAL_MARGIN = 1.5;
|
constexpr coordf_t SUPPORT_MATERIAL_MARGIN = 1.5;
|
||||||
|
|
||||||
class Supports
|
constexpr coordf_t PILLAR_SIZE = 2.5;
|
||||||
|
|
||||||
|
constexpr coordf_t PILLAR_SPACING = 10;
|
||||||
|
|
||||||
|
class SupportMaterial
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrintConfig *print_config; ///<
|
PrintConfig *config; ///<
|
||||||
PrintObjectConfig *print_object_config; ///<
|
PrintObjectConfig *object_config; ///<
|
||||||
Flow flow; ///<
|
Flow flow; ///<
|
||||||
Flow first_layer_flow; ///<
|
Flow first_layer_flow; ///<
|
||||||
Flow interface_flow; ///<
|
Flow interface_flow; ///<
|
||||||
|
|
||||||
Supports(PrintConfig *print_config,
|
SupportMaterial(PrintConfig *print_config,
|
||||||
PrintObjectConfig *print_object_config,
|
PrintObjectConfig *print_object_config,
|
||||||
const Flow &flow,
|
const Flow &flow,
|
||||||
const Flow &first_layer_flow,
|
const Flow &first_layer_flow,
|
||||||
const Flow &interface_flow)
|
const Flow &interface_flow)
|
||||||
: print_config(print_config),
|
: config(print_config),
|
||||||
print_object_config(print_object_config),
|
object_config(print_object_config),
|
||||||
flow(flow),
|
flow(flow),
|
||||||
first_layer_flow(first_layer_flow),
|
first_layer_flow(first_layer_flow),
|
||||||
interface_flow(interface_flow)
|
interface_flow(interface_flow)
|
||||||
@ -49,14 +52,15 @@ public:
|
|||||||
|
|
||||||
void contact_area(PrintObject *object)
|
void contact_area(PrintObject *object)
|
||||||
{
|
{
|
||||||
PrintObjectConfig conf = this->print_object_config;
|
PrintObjectConfig conf = this->object_config;
|
||||||
|
|
||||||
// If user specified a custom angle threshold, convert it to radians.
|
// If user specified a custom angle threshold, convert it to radians.
|
||||||
float threshold_rad;
|
float threshold_rad;
|
||||||
cout << conf.support_material_threshold << endl;
|
cout << conf.support_material_threshold << endl;
|
||||||
if (conf.support_material_threshold > 0) {
|
if (conf.support_material_threshold > 0) {
|
||||||
threshold_rad = deg2rad(conf.support_material_threshold + 1);
|
threshold_rad = Geometry::deg2rad(conf.support_material_threshold.value + 1.0);
|
||||||
cout << "Threshold angle = %d°\n", rad2deg(threshold_rad) << endl;
|
|
||||||
|
// TODO @Samir55 add debug statetments.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build support on a build plate only? If so, then collect top surfaces into $buildplate_only_top_surfaces
|
// Build support on a build plate only? If so, then collect top surfaces into $buildplate_only_top_surfaces
|
||||||
@ -66,7 +70,7 @@ public:
|
|||||||
&& conf.support_material_buildplate_only;
|
&& conf.support_material_buildplate_only;
|
||||||
SurfacesPtr buildplate_only_top_surfaces = SurfacesPtr();
|
SurfacesPtr buildplate_only_top_surfaces = SurfacesPtr();
|
||||||
|
|
||||||
auto contact;
|
Polygons contact;
|
||||||
Polygons overhangs; // This stores the actual overhang supported by each contact layer
|
Polygons overhangs; // This stores the actual overhang supported by each contact layer
|
||||||
|
|
||||||
for (int layer_id = 0; layer_id < object->layers.size(); layer_id++) {
|
for (int layer_id = 0; layer_id < object->layers.size(); layer_id++) {
|
||||||
@ -104,7 +108,7 @@ public:
|
|||||||
// but don't apply the safety offset during the union operation as it would
|
// but don't apply the safety offset during the union operation as it would
|
||||||
// inflate the polygons over and over.
|
// inflate the polygons over and over.
|
||||||
for (auto surface : projection_new) {
|
for (auto surface : projection_new) {
|
||||||
buildplate_only_top_surfaces.push_back(offset(surface, scale(0.01)));
|
// buildplate_only_top_surfaces.push_back(offset(surface, scale_(0.01)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,14 +121,14 @@ public:
|
|||||||
for (auto const &contour : layer->slices.contours()) {
|
for (auto const &contour : layer->slices.contours()) {
|
||||||
auto contour_clone = contour;
|
auto contour_clone = contour;
|
||||||
overhangs.push_back(contour_clone);
|
overhangs.push_back(contour_clone);
|
||||||
contact.push_back(offset(overhangs.back(), static_cast<const float>(SUPPORT_MATERIAL_MARGIN)));
|
// contact.push_back(offset(overhangs.back(), static_cast<const float>(SUPPORT_MATERIAL_MARGIN)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Layer *lower_layer = object->get_layer(layer_id - 1);
|
Layer *lower_layer = object->get_layer(layer_id - 1);
|
||||||
for (auto layerm : layer->regions) {
|
for (auto layerm : layer->regions) {
|
||||||
float fw = layerm->flow(frExternalPerimeter).scaled_width();
|
float fw = layerm->flow(frExternalPerimeter).scaled_width();
|
||||||
auto difference;
|
Polygons difference;
|
||||||
|
|
||||||
// If a threshold angle was specified, use a different logic for detecting overhangs.
|
// If a threshold angle was specified, use a different logic for detecting overhangs.
|
||||||
if ((conf.support_material && threshold_rad > 0)
|
if ((conf.support_material && threshold_rad > 0)
|
||||||
@ -134,10 +138,10 @@ public:
|
|||||||
float layer_threshold_rad = threshold_rad;
|
float layer_threshold_rad = threshold_rad;
|
||||||
if (layer_id <= conf.support_material_enforce_layers) {
|
if (layer_id <= conf.support_material_enforce_layers) {
|
||||||
// Use ~45 deg number for enforced supports if we are in auto.
|
// Use ~45 deg number for enforced supports if we are in auto.
|
||||||
layer_threshold_rad = deg2rad(89);
|
layer_threshold_rad = Geometry::deg2rad(89);
|
||||||
}
|
}
|
||||||
if (layer_threshold_rad > 0) {
|
if (layer_threshold_rad > 0) {
|
||||||
d = scale(lower_layer->height) *
|
d = scale_(lower_layer->height) *
|
||||||
((cos(layer_threshold_rad)) / (sin(layer_threshold_rad)));
|
((cos(layer_threshold_rad)) / (sin(layer_threshold_rad)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,10 +151,11 @@ public:
|
|||||||
// is not too high: in that case, $d will be very small (as we need to catch
|
// is not too high: in that case, $d will be very small (as we need to catch
|
||||||
// very short overhangs), and such contact area would be eaten by the
|
// very short overhangs), and such contact area would be eaten by the
|
||||||
// enforced spacing, resulting in high threshold angles to be almost ignored
|
// enforced spacing, resulting in high threshold angles to be almost ignored
|
||||||
if (d > fw/2) {
|
if (d > fw / 2) {
|
||||||
difference = diff(offset(difference, d - fw/2), lower_layer->slices);
|
difference = diff(offset(difference, d - fw / 2), lower_layer->slices);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// $diff now contains the ring or stripe comprised between the boundary of
|
// $diff now contains the ring or stripe comprised between the boundary of
|
||||||
// lower slices and the centerline of the last perimeter in this overhanging layer.
|
// lower slices and the centerline of the last perimeter in this overhanging layer.
|
||||||
// Void $diff means that there's no upper perimeter whose centerline is
|
// Void $diff means that there's no upper perimeter whose centerline is
|
||||||
@ -162,11 +167,87 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void object_top()
|
ExPolygons *object_top(PrintObject *object, SurfacesPtr contact)
|
||||||
{}
|
{
|
||||||
|
// find object top surfaces
|
||||||
|
// we'll use them to clip our support and detect where does it stick.
|
||||||
|
ExPolygons *top = new ExPolygons();
|
||||||
|
if (object_config->support_material_buildplate_only.value)
|
||||||
|
return top;
|
||||||
|
|
||||||
void support_layers_z()
|
}
|
||||||
{}
|
|
||||||
|
vector<coordf_t> support_layers_z(vector<float> contact_z, vector<float> top_z, coordf_t max_object_layer_height)
|
||||||
|
{
|
||||||
|
// Quick table to check whether a given Z is a top surface.
|
||||||
|
map<float, bool> is_top;
|
||||||
|
for (auto z : top_z) is_top[z] = true;
|
||||||
|
|
||||||
|
// determine layer height for any non-contact layer
|
||||||
|
// we use max() to prevent many ultra-thin layers to be inserted in case
|
||||||
|
// layer_height > nozzle_diameter * 0.75.
|
||||||
|
auto nozzle_diameter = config->nozzle_diameter.get_at(object_config->support_material_extruder - 1);
|
||||||
|
auto support_material_height = (max_object_layer_height, (nozzle_diameter * 0.75));
|
||||||
|
coordf_t _contact_distance = this->contact_distance(support_material_height, nozzle_diameter);
|
||||||
|
|
||||||
|
// Initialize known, fixed, support layers.
|
||||||
|
vector<coordf_t> z;
|
||||||
|
for (auto c_z : contact_z) z.push_back(c_z);
|
||||||
|
for (auto t_z : top_z) {
|
||||||
|
z.push_back(t_z);
|
||||||
|
z.push_back(t_z + _contact_distance);
|
||||||
|
}
|
||||||
|
sort(z.begin(), z.end());
|
||||||
|
|
||||||
|
// Enforce first layer height.
|
||||||
|
coordf_t first_layer_height = object_config->first_layer_height;
|
||||||
|
while (!z.empty() && z.front() <= first_layer_height) z.erase(z.begin());
|
||||||
|
z.insert(z.begin(), first_layer_height);
|
||||||
|
|
||||||
|
// Add raft layers by dividing the space between first layer and
|
||||||
|
// first contact layer evenly.
|
||||||
|
if (object_config->raft_layers > 1 && z.size() >= 2) {
|
||||||
|
// z[1] is last raft layer (contact layer for the first layer object) TODO @Samir55 How so?
|
||||||
|
coordf_t height = (z[1] - z[0]) / (object_config->raft_layers - 1);
|
||||||
|
|
||||||
|
// since we already have two raft layers ($z[0] and $z[1]) we need to insert
|
||||||
|
// raft_layers-2 more
|
||||||
|
int idx = 1;
|
||||||
|
for (int j = 0; j < object_config->raft_layers - 2; j++) {
|
||||||
|
float z_new =
|
||||||
|
roundf(static_cast<float>((z[0] + height * idx) * 100)) / 100; // round it to 2 decimal places.
|
||||||
|
z.insert(z.begin() + idx, z_new);
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create other layers (skip raft layers as they're already done and use thicker layers).
|
||||||
|
for (size_t i = z.size(); i >= object_config->raft_layers; i--) {
|
||||||
|
coordf_t target_height = support_material_height;
|
||||||
|
if (i > 0 && is_top[z[i - 1]]) {
|
||||||
|
target_height = nozzle_diameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enforce first layer height.
|
||||||
|
if ((i == 0 && z[i] > target_height + first_layer_height)
|
||||||
|
|| (z[i] - z[i - 1] > target_height + EPSILON)) {
|
||||||
|
z.insert(z.begin() + i, (z[i] - target_height));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove duplicates and make sure all 0.x values have the leading 0.
|
||||||
|
{
|
||||||
|
set<coordf_t> s;
|
||||||
|
for (auto el : z)
|
||||||
|
s.insert(roundf(static_cast<float>((el * 100)) / 100)); // round it to 2 decimal places.
|
||||||
|
z = vector<coordf_t>();
|
||||||
|
for (auto el : s)
|
||||||
|
z.push_back(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
void generate_interface_layers()
|
void generate_interface_layers()
|
||||||
{}
|
{}
|
||||||
@ -212,9 +293,9 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
float contact_distance(float layer_height, float nozzle_diameter)
|
coordf_t contact_distance(coordf_t layer_height, coordf_t nozzle_diameter)
|
||||||
{
|
{
|
||||||
float extra = static_cast<float>(print_object_config->support_material_contact_distance.value);
|
coordf_t extra = static_cast<float>(object_config->support_material_contact_distance.value);
|
||||||
if (extra == 0) {
|
if (extra == 0) {
|
||||||
return layer_height;
|
return layer_height;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user