Fixes after the merge of changes by @alexrj.

This commit is contained in:
bubnikv 2016-12-08 19:02:16 +01:00
parent 5d18657ac5
commit 126126cc78
14 changed files with 277 additions and 21 deletions

View file

@ -709,7 +709,7 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
PolyTreeToExPolygons(polytree, retval);
}
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
void _clipper_pl(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_)
{
PROFILE_FUNC();
@ -723,7 +723,7 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
ClipperPaths_to_Slic3rMultiPoints(output, retval);
}
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
void _clipper_ln(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_)
{
// convert Lines to Polylines
@ -733,7 +733,7 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
polylines.push_back(*line);
// perform operation
_clipper(clipType, polylines, clip, &polylines, safety_offset_);
_clipper_pl(clipType, polylines, clip, &polylines, safety_offset_);
// convert Polylines to Lines
for (Slic3r::Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline)
@ -750,7 +750,7 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
polylines.push_back(*polygon); // implicit call to split_at_first_point()
// perform clipping
_clipper(clipType, polylines, clip, retval, safety_offset_);
_clipper_pl(clipType, polylines, clip, retval, safety_offset_);
/* If the split_at_first_point() call above happens to split the polygon inside the clipping area
we would get two consecutive polylines instead of a single one, so we go through them in order
@ -796,8 +796,6 @@ void diff(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType*
template void diff<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
template void diff<Slic3r::Polygons, Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polygons* retval, bool safety_offset_);
template void diff<Slic3r::Polygons, Slic3r::Polylines>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
template void diff<Slic3r::Polylines, Slic3r::Polylines>(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
template void diff<Slic3r::Lines, Slic3r::Lines>(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_);
template <class SubjectType, class ResultType>
void diff(const SubjectType &subject, const Slic3r::ExPolygons &clip, ResultType* retval, bool safety_offset_)
@ -850,8 +848,6 @@ void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, Resu
template void intersection<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
template void intersection<Slic3r::Polygons, Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polygons* retval, bool safety_offset_);
template void intersection<Slic3r::Polygons, Slic3r::Polylines>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
template void intersection<Slic3r::Polylines, Slic3r::Polylines>(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
template void intersection<Slic3r::Lines, Slic3r::Lines>(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_);
template <class SubjectType>
SubjectType intersection(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_)

View file

@ -105,10 +105,10 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
const Slic3r::Polygons &clip, Slic3r::Polygons* retval, bool safety_offset_);
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
const Slic3r::Polygons &clip, Slic3r::Polylines* retval);
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
const Slic3r::Polygons &clip, Slic3r::Lines* retval);
void _clipper_pl(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
void _clipper_ln(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_);
template <class SubjectType, class ResultType>
void diff(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_ = false);
@ -121,9 +121,29 @@ Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &c
template <class SubjectType, class ClipType>
Slic3r::ExPolygons diff_ex(const SubjectType &subject, const ClipType &clip, bool safety_offset_ = false);
inline void diff(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_ = false)
{
_clipper_pl(ClipperLib::ctDifference, subject, clip, retval, safety_offset_);
}
inline void diff(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_ = false)
{
_clipper_ln(ClipperLib::ctDifference, subject, clip, retval, safety_offset_);
}
template <class SubjectType, class ResultType>
void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_ = false);
inline void intersection(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_ = false)
{
_clipper_pl(ClipperLib::ctIntersection, subject, clip, retval, safety_offset_);
}
inline void intersection(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_ = false)
{
_clipper_ln(ClipperLib::ctIntersection, subject, clip, retval, safety_offset_);
}
template <class SubjectType>
SubjectType intersection(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
@ -133,6 +153,14 @@ intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, b
template <class SubjectType>
bool intersects(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
inline Slic3r::Polylines
intersection_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
{
Slic3r::Polylines polylines_out;
_clipper_pl(ClipperLib::ctIntersection, subject, clip, &polylines_out, safety_offset_);
return polylines_out;
}
void xor_(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval,
bool safety_offset_ = false);

View file

@ -803,7 +803,7 @@ void gcode_spread_points(
const Cell &cell = cells[i];
acc[cell.idx.y()][cell.idx.x()] = (1.f - cell.fraction_covered) * cell.volume + cell.fraction_covered * cell.area * height_avg;
}
} else if (simulationType == ExtrusionSimulationSpreadExcess) {
} else if (simulationType == Slic3r::ExtrusionSimulationSpreadExcess) {
// The volume under the circle does not fit.
// 1) Fill the underfilled cells and remove them from the list.
float volume_borrowed_total = 0.;

View file

@ -13,7 +13,7 @@ enum ExtrusionSimulationType
ExtrusionSimulationDontSpread,
ExtrisopmSimulationSpreadNotOverfilled,
ExtrusionSimulationSpreadFull,
ExtrusionSimulationSpreadExcess,
ExtrusionSimulationSpreadExcess
};
// An opaque class, to keep the boost stuff away from the header.

View file

@ -11,9 +11,6 @@
namespace Slic3r {
typedef std::pair<coordf_t,coordf_t> t_layer_height_range;
typedef std::map<t_layer_height_range,coordf_t> t_layer_height_ranges;
class Layer;
class PrintRegion;
class PrintObject;

View file

@ -6,6 +6,7 @@
#include "Layer.hpp"
#include "Point.hpp"
#include "TriangleMesh.hpp"
#include "Slicing.hpp"
#include <map>
#include <string>
#include <utility>

View file

@ -178,7 +178,7 @@ namespace boost { namespace polygon {
static inline Slic3r::Polygon& set_points(Slic3r::Polygon& polygon, iT input_begin, iT input_end) {
polygon.points.clear();
while (input_begin != input_end) {
polygon.points.push_back(Point());
polygon.points.push_back(Slic3r::Point());
boost::polygon::assign(polygon.points.back(), *input_begin);
++input_begin;
}

View file

@ -154,7 +154,7 @@ private:
// TODO: call model_object->get_bounding_box() instead of accepting
// parameter
PrintObject(Print* print, ModelObject* model_object, const BoundingBoxf3 &modobj_bbox);
~PrintObject();
~PrintObject() {}
};
typedef std::vector<PrintObject*> PrintObjectPtrs;

View file

@ -974,7 +974,7 @@ PrintObject::_make_perimeters()
// check whether a portion of the upper slices falls inside the critical area
const Polylines intersection = intersection_pl(
upper_layerm_polygons,
to_polylines(upper_layerm_polygons),
critical_area
);

View file

@ -0,0 +1,44 @@
// Based on implementation by @platsch
#ifndef slic3r_Slicing_hpp_
#define slic3r_Slicing_hpp_
#include "libslic3r.h"
namespace Slic3r
{
struct SlicingParameters
{
SlicingParameters() { memset(this, 0, sizeof(SlicingParameters)); }
// The regular layer height, applied for all but the first layer, if not overridden by layer ranges
// or by the variable layer thickness table.
coordf_t layer_height;
// Thickness of the first layer. This is either the first print layer thickness if printed without a raft,
// or a bridging flow thickness if printed over a non-soluble raft,
// or a normal layer height if printed over a soluble raft.
coordf_t first_layer_height;
// If the object is printed over a non-soluble raft, the first layer may be printed with a briding flow.
bool first_layer_bridging;
// Minimum / maximum layer height, to be used for the automatic adaptive layer height algorithm,
// or by an interactive layer height editor.
coordf_t min_layer_height;
coordf_t max_layer_height;
// Bottom and top of the printed object.
// If printed without a raft, object_print_z_min = 0 and object_print_z_max = object height.
// Otherwise object_print_z_min is equal to the raft height.
coordf_t object_print_z_min;
coordf_t object_print_z_max;
};
typedef std::pair<coordf_t,coordf_t> t_layer_height_range;
typedef std::map<t_layer_height_range,coordf_t> t_layer_height_ranges;
}; // namespace Slic3r
#endif /* slic3r_Slicing_hpp_ */

View file

@ -0,0 +1,149 @@
#include "libslic3r.h"
#include "TriangleMesh.hpp"
#include "SlicingAdaptive.hpp"
namespace Slic3r
{
void SlicingAdaptive::clear()
{
m_meshes.clear();
m_faces.clear();
m_face_normal_z.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));
}
void SlicingAdaptive::prepare()
{
// 1) Collect faces of all meshes.
{
int nfaces_total = 0;
for (std::vector<const TriangleMesh*>::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh)
nfaces_total += (*it_mesh)->stl.stats.number_of_facets;
m_faces.reserve(nfaces_total);
}
m_max_z = 0;
for (std::vector<const TriangleMesh*>::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) {
const stl_facet *faces = (*it_mesh)->stl.facet_start;
int nfaces = (*it_mesh)->stl.stats.number_of_facets;
for (int i = 0; i < nfaces; ++ i) {
const stl_facet *facet = faces + i;
m_faces.push_back(facet);
m_max_z = std::max(std::max(m_max_z, facet->vertex[0].z), std::max(facet->vertex[1].z, facet->vertex[2].z));
}
}
// 2) Sort faces lexicographically by their Z span.
std::sort(m_faces.begin(), m_faces.end(), [](const stl_facet *f1, const stl_facet *f2) {
std::pair<float, float> span1 = face_z_span(f1);
std::pair<float, float> span2 = face_z_span(f2);
return span1 < span2;
});
// 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;
}
float SlicingAdaptive::cusp_height(float z, float cusp_value, int &current_facet)
{
float height = m_layer_height_max;
bool first_hit = false;
// find all facets intersecting the slice-layer
int ordered_id = current_facet;
for (; ordered_id < int(m_faces.size()); ++ ordered_id) {
std::pair<float, float> zspan = face_z_span(m_faces[ordered_id]);
// facet's minimum is higher than slice_z -> end loop
if (zspan.first >= z)
break;
// facet's maximum is higher than slice_z -> store the first event for next cusp_height call to begin at this point
if (zspan.second > z) {
// first event?
if (! first_hit) {
first_hit = true;
current_facet = ordered_id;
}
// skip touching facets which could otherwise cause small cusp values
if (zspan.second <= z + EPSILON)
continue;
// compute cusp-height for this facet and store minimum of all heights
float normal_z = m_face_normal_z[ordered_id];
height = std::min(height, (normal_z == 0) ? 9999 : abs(cusp_value / normal_z));
}
}
// lower height limit due to printer capabilities
height = std::max(height, m_layer_height_min);
// check for sloped facets inside the determined layer and correct height if necessary
if (height > m_layer_height_min) {
for (; ordered_id < int(m_faces.size()); ++ ordered_id) {
std::pair<float, float> zspan = face_z_span(m_faces[ordered_id]);
// facet's minimum is higher than slice_z + height -> end loop
if (zspan.first >= z + height)
break;
// skip touching facets which could otherwise cause small cusp values
if (zspan.second <= z + EPSILON)
continue;
// Compute cusp-height for this facet and check against height.
float normal_z = m_face_normal_z[ordered_id];
float cusp = (normal_z == 0) ? 9999 : abs(cusp_value / normal_z);
float z_diff = zspan.first - z;
// handle horizontal facets
if (m_face_normal_z[ordered_id] > 0.999) {
// Slic3r::debugf "cusp computation, height is reduced from %f", $height;
height = z_diff;
// Slic3r::debugf "to %f due to near horizontal facet\n", $height;
} else if (cusp > z_diff) {
if (cusp < height) {
// Slic3r::debugf "cusp computation, height is reduced from %f", $height;
height = cusp;
// Slic3r::debugf "to %f due to new cusp height\n", $height;
}
} else {
// Slic3r::debugf "cusp computation, height is reduced from %f", $height;
height = z_diff;
// Slic3r::debugf "to z-diff: %f\n", $height;
}
}
// lower height limit due to printer capabilities again
height = std::max(height, m_layer_height_min);
}
// Slic3r::debugf "cusp computation, layer-bottom at z:%f, cusp_value:%f, resulting layer height:%f\n", unscale $z, $cusp_value, $height;
return height;
}
// Returns the distance to the next horizontal facet in Z-dir
// to consider horizontal object features in slice thickness
float SlicingAdaptive::horizontal_facet_distance(float z)
{
for (size_t i = 0; i < m_faces.size(); ++ i) {
std::pair<float, float> zspan = face_z_span(m_faces[i]);
// facet's minimum is higher than max forward distance -> end loop
if (zspan.first > z + m_layer_height_max)
break;
// min_z == max_z -> horizontal facet
if (zspan.first > z && zspan.first == zspan.second)
return zspan.first - z;
}
// objects maximum?
return (z + m_layer_height_max > m_max_z) ?
std::max<float>(m_max_z - z, 0.f) :
m_layer_height_max;
}
}; // namespace Slic3r

View file

@ -0,0 +1,38 @@
// Based on implementation by @platsch
#ifndef slic3r_SlicingAdaptive_hpp_
#define slic3r_SlicingAdaptive_hpp_
#include "Slicing.hpp"
#include "admesh/stl.h"
namespace Slic3r
{
class TriangleMesh;
class SlicingAdaptive
{
public:
void clear();
void set_layer_height_range(float min, float max) { m_layer_height_min = min; m_layer_height_max = max; }
void add_mesh(const TriangleMesh *mesh) { m_meshes.push_back(mesh); }
void prepare();
float cusp_height(float z, float cusp_value, int &current_facet);
float horizontal_facet_distance(float z);
protected:
float m_layer_height_min;
float m_layer_height_max;
float m_max_z;
std::vector<const TriangleMesh*> m_meshes;
// Collected faces of all meshes, sorted by raising Z of the bottom most face.
std::vector<const stl_facet*> m_faces;
// Z component of face normals, normalized.
std::vector<float> m_face_normal_z;
};
}; // namespace Slic3r
#endif /* slic3r_SlicingAdaptive_hpp_ */

View file

@ -8,7 +8,6 @@
#include "EdgeGrid.hpp"
#include <cmath>
#include <cassert>
#include <memory>
#include <boost/log/trivial.hpp>
#include <unordered_set>
@ -21,6 +20,8 @@
#include "SVG.hpp"
#endif
#include <cassert>
namespace Slic3r {
// Increment used to reach MARGIN in steps to avoid trespassing thin objects

View file

@ -163,4 +163,6 @@ SV* polynode2perl(const ClipperLib::PolyNode& node);
#endif
#endif
using namespace Slic3r;
#endif