mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-06 15:21:09 +00:00
Merge branch 'main' into belt-printer
This commit is contained in:
@@ -61,6 +61,7 @@ CheckOptions:
|
||||
termios\.h;
|
||||
[/\\](um|shared)[/\\].*;
|
||||
sal\.h;
|
||||
tchar\.h;
|
||||
clipper[/\\]clipper\.hpp;
|
||||
png(lib)?conf\.h;
|
||||
mcut[/\\]platform\.h;
|
||||
|
||||
@@ -153,6 +153,8 @@ using namespace nlohmann;
|
||||
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/Jobs/SendJob.hpp"
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ extern "C"
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <boost/algorithm/string/constants.hpp>
|
||||
|
||||
#ifdef SLIC3R_GUI
|
||||
class OpenGLVersionCheck
|
||||
|
||||
@@ -11,6 +11,14 @@
|
||||
|
||||
#include "git_commit_hash.h"
|
||||
#include "libslic3r_version.h"
|
||||
#include "StackWalker.h"
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
#include <cstdarg>
|
||||
#include <cstddef>
|
||||
#include <ctime>
|
||||
#include <excpt.h>
|
||||
|
||||
static std::string g_log_folder;
|
||||
static std::atomic<int> g_crash_log_count = 0;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
#include "StackWalker.h"
|
||||
#include <eh.h>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
class CBaseException : public CStackWalker
|
||||
{
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#include <strsafe.h>
|
||||
//#include <atlconv.h>
|
||||
#include <dbghelp.h>
|
||||
#include <cstdarg>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#pragma comment(lib, "version.lib")
|
||||
#pragma comment( lib, "dbghelp.lib" )
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <Windows.h>
|
||||
#include <tchar.h>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
|
||||
namespace textconv_helper
|
||||
{
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
#include <string_view>
|
||||
|
||||
#ifdef WIN32
|
||||
//FIXME replace the two following includes with <boost/md5.hpp> after it becomes mainstream.
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#include <cstdio>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <psapi.h>
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "libslic3r/AABBTreeLines.hpp" // search structure for found close points
|
||||
#include "libslic3r/Line.hpp"
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include <sstream>
|
||||
|
||||
// Experimentaly suggested ration of font ascent by multiple fonts
|
||||
// to get approx center of normal text line
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "FuzzySkin.hpp"
|
||||
|
||||
#include "libnoise/noise.h"
|
||||
#include <functional>
|
||||
|
||||
// #define DEBUG_FUZZY
|
||||
|
||||
|
||||
@@ -301,6 +301,9 @@ struct SurfaceFillParams
|
||||
float skin_infill_depth = 0;
|
||||
bool symmetric_infill_y_axis = false;
|
||||
|
||||
// Top fill for 3D honeycomb
|
||||
bool infill_complete_top = false;
|
||||
|
||||
// Params for Lateral honeycomb
|
||||
float infill_overhang_angle = 60.f;
|
||||
|
||||
@@ -344,6 +347,7 @@ struct SurfaceFillParams
|
||||
RETURN_COMPARE_NON_EQUAL(lateral_lattice_angle_1);
|
||||
RETURN_COMPARE_NON_EQUAL(lateral_lattice_angle_2);
|
||||
RETURN_COMPARE_NON_EQUAL(symmetric_infill_y_axis);
|
||||
RETURN_COMPARE_NON_EQUAL(infill_complete_top);
|
||||
RETURN_COMPARE_NON_EQUAL(infill_lock_depth);
|
||||
RETURN_COMPARE_NON_EQUAL(skin_infill_depth);
|
||||
RETURN_COMPARE_NON_EQUAL(infill_overhang_angle);
|
||||
@@ -931,6 +935,8 @@ std::vector<SurfaceFill> group_fills(const Layer &layer, LockRegionParam &lock_p
|
||||
params.symmetric_infill_y_axis = region_config.symmetric_infill_y_axis;
|
||||
} else if (params.pattern == ipZigZag) {
|
||||
params.symmetric_infill_y_axis = region_config.symmetric_infill_y_axis;
|
||||
} else if (params.pattern == ip3DHoneycomb) {
|
||||
params.infill_complete_top = region_config.infill_complete_top;
|
||||
}
|
||||
|
||||
if (surface.is_solid()) {
|
||||
@@ -1430,6 +1436,8 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
||||
} else if (surface_fill.params.pattern == ipZigZag) {
|
||||
params.symmetric_infill_y_axis = surface_fill.params.symmetric_infill_y_axis;
|
||||
|
||||
} else if (surface_fill.params.pattern == ip3DHoneycomb) {
|
||||
params.infill_complete_top = surface_fill.params.infill_complete_top;
|
||||
}
|
||||
if (surface_fill.params.pattern == ipGrid)
|
||||
params.can_reverse = false;
|
||||
|
||||
@@ -61,7 +61,7 @@ static coordf_t troctWave(coordf_t pos, coordf_t gridSize, coordf_t Zpos)
|
||||
|
||||
// Identify the important points of curve change within a truncated
|
||||
// octahedron wave (as waveform fraction t):
|
||||
// 1. Start of wave (always 0.0)
|
||||
// 1. Start of wave (always 0.0; not needed if the pattern base starts here)
|
||||
// 2. Transition to upper "horizontal" part
|
||||
// 3. Transition from upper "horizontal" part
|
||||
// 4. Transition to lower "horizontal" part
|
||||
@@ -73,17 +73,11 @@ static coordf_t troctWave(coordf_t pos, coordf_t gridSize, coordf_t Zpos)
|
||||
* \ /
|
||||
* o---o
|
||||
*/
|
||||
static std::vector<coordf_t> getCriticalPoints(coordf_t Zpos, coordf_t gridSize)
|
||||
static std::vector<coordf_t> getCriticalPoints(coordf_t Zpos, coordf_t gridSize)
|
||||
{
|
||||
std::vector<coordf_t> res = {0.};
|
||||
std::vector<coordf_t> res;
|
||||
coordf_t perpOffset = abs(triWave(Zpos, gridSize) / 2.);
|
||||
|
||||
coordf_t normalisedOffset = perpOffset / gridSize;
|
||||
// // for debugging: just generate evenly-distributed points
|
||||
// for(coordf_t i = 0; i < 2; i += 0.05){
|
||||
// res.push_back(gridSize * i);
|
||||
// }
|
||||
// note: 0 == straight line
|
||||
if(normalisedOffset > 0){
|
||||
res.push_back(gridSize * (0. + normalisedOffset));
|
||||
res.push_back(gridSize * (1. - normalisedOffset));
|
||||
@@ -93,113 +87,251 @@ static std::vector<coordf_t> getCriticalPoints(coordf_t Zpos, coordf_t gridSize)
|
||||
return(res);
|
||||
}
|
||||
|
||||
// Generate an array of points that are in the same direction as the
|
||||
// basic printing line (i.e. Y points for columns, X points for rows)
|
||||
// Note: a negative offset only causes a change in the perpendicular
|
||||
// direction
|
||||
static std::vector<coordf_t> colinearPoints(const coordf_t Zpos, coordf_t gridSize, std::vector<coordf_t> critPoints,
|
||||
const size_t baseLocation, size_t gridLength)
|
||||
// Add additional dense fill in line with the pattern direction to
|
||||
// cover the top squares of the pattern
|
||||
static Polylines addTops(coordf_t Zpos, coordf_t gridSize, coordf_t lengthX, coordf_t lengthY, coordf_t spacing,
|
||||
size_t multiline_count, size_t topDistance)
|
||||
{
|
||||
std::vector<coordf_t> points;
|
||||
points.push_back(baseLocation);
|
||||
for (coordf_t cLoc = baseLocation; cLoc < gridLength; cLoc+= (gridSize*2)) {
|
||||
for(size_t pi = 0; pi < critPoints.size(); pi++){
|
||||
points.push_back(baseLocation + cLoc + critPoints[pi]);
|
||||
coordf_t zCycle = fmod(Zpos + gridSize/2, gridSize * 2.) / (gridSize * 2.);
|
||||
coordf_t zHalfCycle = fmod(zCycle, 0.5) * 2.;
|
||||
bool printVert = zCycle < 0.5;
|
||||
coordf_t offsetX = multiline_count;
|
||||
coordf_t offsetY = multiline_count;
|
||||
coordf_t perpOffset = abs(triWave(Zpos, gridSize) / 2.);
|
||||
coordf_t gridPoint = gridSize * (0. + perpOffset / gridSize);
|
||||
coordf_t topOffset = gridSize / 2.0 - abs(troctWave(gridPoint, gridSize, Zpos));
|
||||
coordf_t multilineAdjust = (sqrt(2) - 1.0) / 2.;
|
||||
Polylines lines;
|
||||
size_t pointCount = 0;
|
||||
coordf_t gridStartL = gridSize * 0.5 - topOffset;
|
||||
coordf_t gridEndL = gridSize * 0.5 + topOffset;
|
||||
if((topDistance == 0) && (multiline_count == 1)){
|
||||
// extend out a little bit on the first layer to help fuse the cover
|
||||
gridStartL -= spacing;
|
||||
gridEndL += spacing;
|
||||
} else if(multiline_count > 1) {
|
||||
// match start point to the corner edge
|
||||
gridStartL -= spacing * multiline_count * multilineAdjust;
|
||||
gridEndL += spacing * multiline_count * multilineAdjust;
|
||||
}
|
||||
// top cover extents perpendicular to the direction of travel
|
||||
coordf_t gridStartP = gridSize * 0.5 - topOffset + spacing * multiline_count / 2. + spacing / 2.;
|
||||
coordf_t gridEndP = gridSize * 0.5 + topOffset - spacing * multiline_count / 2. - spacing / 2.;
|
||||
coordf_t x, y;
|
||||
int xm, ym;
|
||||
// if the print direction needs to be rotated, then swap the extents
|
||||
if((topDistance % 2) == 0){
|
||||
std::swap(gridStartL, gridStartP);
|
||||
std::swap(gridEndL, gridEndP);
|
||||
}
|
||||
// adjust spacing so that it starts and ends on exactly the right place
|
||||
// and increase fill density slightly to reduce gaps
|
||||
coordf_t region_count = floor((gridEndP - gridStartP) / (spacing / sqrt(2)));
|
||||
if(region_count <= 0){
|
||||
return lines;
|
||||
}
|
||||
spacing = (gridEndP - gridStartP) / region_count;
|
||||
for (x = offsetX, xm = 0; x <= (lengthX); x+= gridSize, xm = xm ^ 1) {
|
||||
for (y = offsetY, ym = 0; y <= (lengthY); y += gridSize, ym = ym ^ 1) {
|
||||
if(((xm ^ ym) == 1) == printVert){
|
||||
continue;
|
||||
}
|
||||
// // For debugging: remove 0,0 -> 1,1 top to help understand orientation
|
||||
// if((x <= (gridSize + EPSILON)) && (y <= (gridSize + EPSILON)) && ((y - x) < EPSILON)){
|
||||
// continue;
|
||||
// }
|
||||
Polyline newPoints;
|
||||
int dirMod = xm ^ ym;
|
||||
if(printVert == (topDistance % 2)){
|
||||
if(y < (lengthY - spacing * multiline_count * 1.5)){
|
||||
coordf_t endPMod = std::min(lengthX - (multiline_count * (spacing + 1) / 2.), x + gridEndP) - x;
|
||||
coordf_t endLMod = std::min(lengthY - (multiline_count * (spacing + 1) / 2.), y + gridEndL) - y;
|
||||
for(coordf_t xi = gridStartP; xi < (endPMod + EPSILON); xi += spacing, dirMod = dirMod ^ 1){
|
||||
newPoints.points.push_back((dirMod == 0) ? Point(x + xi, y + gridStartL) : Point(x + xi, y + endLMod));
|
||||
newPoints.points.push_back((dirMod == 0) ? Point(x + xi, y + endLMod) : Point(x + xi, y + gridStartL));
|
||||
pointCount += 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(x < (lengthX - spacing * multiline_count * 1.5)){
|
||||
coordf_t endPMod = std::min(lengthY - (multiline_count * (spacing + 1) / 2.), y + gridEndP) - y;
|
||||
coordf_t endLMod = std::min(lengthX - (multiline_count * (spacing + 1) / 2.), x + gridEndL) - x;
|
||||
for(coordf_t yi = gridStartP; yi < (endPMod + EPSILON); yi += spacing, dirMod = dirMod ^ 1){
|
||||
newPoints.points.push_back((dirMod == 0) ? Point(x + gridStartL, y + yi) : Point(x + endLMod, y + yi));
|
||||
newPoints.points.push_back((dirMod == 0) ? Point(x + endLMod, y + yi) : Point(x + gridStartL, y + yi));
|
||||
pointCount += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
lines.push_back(newPoints);
|
||||
}
|
||||
}
|
||||
points.push_back(gridLength);
|
||||
return points;
|
||||
return lines;
|
||||
}
|
||||
|
||||
// Generate an array of points for the dimension that is perpendicular to
|
||||
// the basic printing line (i.e. X points for columns, Y points for rows)
|
||||
static std::vector<coordf_t> perpendPoints(const coordf_t Zpos, coordf_t gridSize, std::vector<coordf_t> critPoints,
|
||||
size_t baseLocation, size_t gridLength,
|
||||
size_t offsetBase, coordf_t perpDir)
|
||||
// Generate a set of polylines that complete octahedron curves on the
|
||||
// extremities of a pattern
|
||||
static Polylines makeEndPoints(const coordf_t Zpos, coordf_t gridSize, std::vector<coordf_t> critPoints,
|
||||
coordf_t lengthX, coordf_t lengthY, coordf_t spacing, size_t multiline_count)
|
||||
{
|
||||
std::vector<coordf_t> points;
|
||||
points.push_back(offsetBase);
|
||||
for (coordf_t cLoc = baseLocation; cLoc < gridLength; cLoc+= gridSize*2) {
|
||||
for(size_t pi = 0; pi < critPoints.size(); pi++){
|
||||
Polylines lines;
|
||||
coordf_t zCycle = fmod(Zpos + gridSize/2, gridSize * 2.) / (gridSize * 2.);
|
||||
bool printVert = zCycle < 0.5;
|
||||
bool printHoriz = zCycle >= 0.5;
|
||||
int zFlipOffset = ((sgn(fmod(zCycle, 0.5) - 0.25) > 0) == printVert) ? 0 : 1;
|
||||
// create templates for copying
|
||||
Polylines startLines, endLines;
|
||||
for(size_t li = 0; li < multiline_count; li++){
|
||||
coordf_t oAdj = (li - ((multiline_count - 1) / 2.)) * spacing; // orthogonal line adjustment
|
||||
coordf_t dAdj = oAdj * sqrt(2); // diagonal line adjustment
|
||||
Polyline startLine, endLine;
|
||||
// Left Bottom; Bottom Left
|
||||
startLine.points.push_back(printHoriz ? Point(oAdj, -dAdj) : Point(-dAdj, oAdj));
|
||||
// Right Bottom; Top Left
|
||||
endLine.points.push_back(printHoriz ? Point(-oAdj, -dAdj) : Point(-dAdj, -oAdj));
|
||||
for(size_t pi = 0; pi < 2; pi++){
|
||||
int pDir = pi * 2 - 1;
|
||||
coordf_t pAdj = pDir * (sqrt(2) - 1) * oAdj;
|
||||
coordf_t troctOffset = abs(troctWave(critPoints[pi], gridSize, Zpos));
|
||||
startLine.points.push_back(printHoriz ?
|
||||
Point(-troctOffset, critPoints[pi] + pAdj) :
|
||||
Point(critPoints[pi] + pAdj, -troctOffset));
|
||||
endLine.points.push_back(printHoriz ?
|
||||
Point(troctOffset, critPoints[pi] + pAdj) :
|
||||
Point(critPoints[pi] + pAdj, troctOffset));
|
||||
}
|
||||
// Left Top; Bottom Right
|
||||
startLine.points.push_back(printHoriz ? Point(oAdj, gridSize + dAdj) : Point(gridSize + dAdj, oAdj));
|
||||
// Right Top; Top Right
|
||||
endLine.points.push_back(printHoriz ? Point(-oAdj, gridSize + dAdj) : Point(gridSize + dAdj, -oAdj));
|
||||
startLines.push_back(startLine);
|
||||
endLines.push_back(endLine);
|
||||
}
|
||||
coordf_t gridMaxX = ceil((lengthX - EPSILON) / gridSize) * gridSize;
|
||||
coordf_t gridMaxY = ceil((lengthY - EPSILON) / gridSize) * gridSize;
|
||||
for(size_t li = 0; li < multiline_count; li++){
|
||||
coordf_t mlFactor = (li - ((multiline_count - 1) / 2.)) * spacing;
|
||||
for (coordf_t cLoc = zFlipOffset * gridSize; cLoc < ((printHoriz ? gridMaxY : gridMaxX) - EPSILON); cLoc += gridSize * 2) {
|
||||
Polyline tsLine(startLines[li]);
|
||||
Polyline teLine(endLines[li]);
|
||||
tsLine.translate(printVert ? Point(cLoc, -mlFactor) : Point(-mlFactor, cLoc));
|
||||
teLine.translate(printVert ? Point(cLoc, gridMaxY + mlFactor) : Point(gridMaxX + mlFactor, cLoc));
|
||||
lines.push_back(tsLine);
|
||||
lines.push_back(teLine);
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
// Generate a polyline that describes a single path segment through
|
||||
// the infill in the same direction as the basic printing line (i.e. X
|
||||
// points for columns, Y points for rows)
|
||||
static Polyline patternPoints(const coordf_t Zpos, coordf_t gridSize, std::vector<coordf_t> critPoints,
|
||||
coordf_t gridLength, coordf_t perpDir, int print_dir, coordf_t oAdj)
|
||||
{
|
||||
Polyline line;
|
||||
coordf_t dAdj = oAdj * (sqrt(2) - 1); // additional diagonal adjustment
|
||||
coordf_t zCycle = fmod(Zpos + gridSize/2, gridSize * 2.) / (gridSize * 2.);
|
||||
int zFlipDirection = sgn(fmod(zCycle, 0.5) - 0.25);
|
||||
bool hitEnd = false;
|
||||
int endPi = -1;
|
||||
size_t pi = 0;
|
||||
size_t piOfs = 0;
|
||||
line.points.push_back((print_dir == 1) ? Point(dAdj, 0.) : Point(0., dAdj));
|
||||
coordf_t gridMax = ceil((gridLength - EPSILON) / gridSize) * gridSize;
|
||||
for (coordf_t cLoc = 0; cLoc < gridMax; cLoc += gridSize, piOfs = (piOfs + 2) % 4) {
|
||||
for(pi = piOfs; pi < (piOfs + 2); pi++){
|
||||
coordf_t offset = troctWave(critPoints[pi], gridSize, Zpos);
|
||||
points.push_back(offsetBase + (offset * perpDir));
|
||||
coordf_t offsetFlip = sgn(offset);
|
||||
coordf_t posFlip = floor(((pi + 1) % 4) / 2) * 2 - 1;
|
||||
coordf_t posLin = cLoc - (piOfs * gridSize / 2.) + critPoints[pi];
|
||||
coordf_t posPerp = offset * perpDir;
|
||||
line.points.push_back((print_dir == 1) ?
|
||||
Point(posPerp, posLin + posFlip * dAdj * perpDir * zFlipDirection * print_dir) :
|
||||
Point(posLin + posFlip * dAdj * perpDir * zFlipDirection * print_dir, posPerp));
|
||||
}
|
||||
}
|
||||
points.push_back(offsetBase);
|
||||
return points;
|
||||
}
|
||||
|
||||
static inline Pointfs zip(const std::vector<coordf_t> &x, const std::vector<coordf_t> &y)
|
||||
{
|
||||
assert(x.size() == y.size());
|
||||
Pointfs out;
|
||||
out.reserve(x.size());
|
||||
for (size_t i = 0; i < x.size(); ++ i)
|
||||
out.push_back(Vec2d(x[i], y[i]));
|
||||
return out;
|
||||
line.points.push_back((print_dir == 1) ? Point(dAdj, gridMax) : Point(gridMax, dAdj));
|
||||
return line;
|
||||
}
|
||||
|
||||
// Generate a set of curves (array of array of 2d points) that describe a
|
||||
// horizontal slice of a truncated regular octahedron.
|
||||
static std::vector<Pointfs> makeActualGrid(coordf_t Zpos, coordf_t gridSize, size_t boundsX, size_t boundsY)
|
||||
static Polylines makeZigZag(coordf_t Zpos, coordf_t gridSize, coordf_t lengthX, coordf_t lengthY,
|
||||
coordf_t spacing, size_t multiline_count)
|
||||
{
|
||||
std::vector<Pointfs> points;
|
||||
Polylines lines;
|
||||
std::vector<coordf_t> critPoints = getCriticalPoints(Zpos, gridSize);
|
||||
coordf_t zCycle = fmod(Zpos + gridSize/2, gridSize * 2.) / (gridSize * 2.);
|
||||
bool printVert = zCycle < 0.5;
|
||||
if (printVert) {
|
||||
int perpDir = -1;
|
||||
for (coordf_t x = 0; x <= (boundsX); x+= gridSize, perpDir *= -1) {
|
||||
points.push_back(Pointfs());
|
||||
Pointfs &newPoints = points.back();
|
||||
newPoints = zip(
|
||||
perpendPoints(Zpos, gridSize, critPoints, 0, boundsY, x, perpDir),
|
||||
colinearPoints(Zpos, gridSize, critPoints, 0, boundsY));
|
||||
BoundingBox extents;
|
||||
int perpDir = -1;
|
||||
int perpDirPattern = -1;
|
||||
coordf_t gridMax = ceil(((printVert ? lengthX : lengthY) - EPSILON) / gridSize) * gridSize;
|
||||
for (coordf_t pPos = 0; pPos < gridMax; pPos += gridSize, perpDirPattern *= -1) {
|
||||
for (size_t li = 0; li < multiline_count; li++){
|
||||
coordf_t oAdj = (li - ((multiline_count - 1) / 2.)) * spacing; // orthogonal line adjustment
|
||||
Polyline newPoints;
|
||||
newPoints = patternPoints(Zpos, gridSize, critPoints,
|
||||
printVert ? lengthY : lengthX,
|
||||
perpDirPattern, printVert ? 1 : -1, oAdj);
|
||||
if (perpDir == 1)
|
||||
std::reverse(newPoints.begin(), newPoints.end());
|
||||
}
|
||||
} else {
|
||||
int perpDir = 1;
|
||||
for (coordf_t y = gridSize; y <= (boundsY); y+= gridSize, perpDir *= -1) {
|
||||
points.push_back(Pointfs());
|
||||
Pointfs &newPoints = points.back();
|
||||
newPoints = zip(
|
||||
colinearPoints(Zpos, gridSize, critPoints, 0, boundsX),
|
||||
perpendPoints(Zpos, gridSize, critPoints, 0, boundsX, y, perpDir));
|
||||
if (perpDir == -1)
|
||||
std::reverse(newPoints.begin(), newPoints.end());
|
||||
std::reverse(newPoints.points.begin(), newPoints.points.end());
|
||||
newPoints.translate(printVert ? Point(pPos + oAdj, 0.) : Point(0., pPos + oAdj));
|
||||
extents.merge(newPoints.points);
|
||||
lines.push_back(newPoints);
|
||||
perpDir *= -1;
|
||||
}
|
||||
}
|
||||
return points;
|
||||
return lines;
|
||||
}
|
||||
|
||||
// Generate a set of curves (array of array of 2d points) that describe a
|
||||
// horizontal slice of a truncated regular octahedron with a specified
|
||||
// grid square size.
|
||||
// gridWidth and gridHeight define the width and height of the bounding box respectively
|
||||
static Polylines makeGrid(coordf_t z, coordf_t gridSize, coordf_t boundWidth, coordf_t boundHeight, bool fillEvenly)
|
||||
// Note: this uses the 'complete' infill parameter to determine if the
|
||||
// square tops should be enclosed (true) or open (false). Alternatively,
|
||||
// a rotation angle of 180 degrees or greater can be used.
|
||||
static Polylines makeGrid(coordf_t z, coordf_t zLast, coordf_t gridSize,
|
||||
coordf_t lengthX, coordf_t lengthY,
|
||||
bool completeTops, coordf_t spacing, size_t multiline_count, size_t layer_count)
|
||||
{
|
||||
std::vector<Pointfs> polylines = makeActualGrid(z, gridSize, boundWidth, boundHeight);
|
||||
coordf_t zCycle = fmod(z + gridSize/2, gridSize * 2.) / (gridSize * 2.);
|
||||
bool printVert = zCycle < 0.5;
|
||||
coordf_t zCycleLast = fmod(zLast + gridSize/2, gridSize * 2.) / (gridSize * 2.);
|
||||
bool printVertLast = zCycleLast < 0.5;
|
||||
Polylines result;
|
||||
result.reserve(polylines.size());
|
||||
for (std::vector<Pointfs>::const_iterator it_polylines = polylines.begin();
|
||||
it_polylines != polylines.end(); ++ it_polylines) {
|
||||
result.push_back(Polyline());
|
||||
Polyline &polyline = result.back();
|
||||
for (Pointfs::const_iterator it = it_polylines->begin(); it != it_polylines->end(); ++ it)
|
||||
polyline.points.push_back(Point(coord_t((*it)(0)), coord_t((*it)(1))));
|
||||
Polylines polyZag = makeZigZag(z, gridSize, lengthX, lengthY, spacing, multiline_count);
|
||||
result.insert(result.end(), polyZag.begin(), polyZag.end());
|
||||
// add end connectors
|
||||
std::vector<coordf_t> critPoints = getCriticalPoints(z, gridSize);
|
||||
Polylines endPoints = makeEndPoints(z, gridSize, critPoints, lengthX, lengthY, spacing, multiline_count);
|
||||
result.insert(result.end(), endPoints.begin(), endPoints.end());
|
||||
// add tops for the first <multiline_count> layers in each cycle
|
||||
if(completeTops && (printVert != printVertLast)){
|
||||
coordf_t layerHeight = (z - zLast) / (multiline_count * layer_count);
|
||||
size_t top_distance = 0;
|
||||
for(coordf_t zCheck = z; zCheck >= (zLast + EPSILON); zCheck -= layerHeight * layer_count, top_distance++){
|
||||
coordf_t zCheckCycle = fmod(zCheck + gridSize/2, gridSize * 2.) / (gridSize * 2.);
|
||||
if(printVert != (zCheckCycle < 0.5)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
Polylines polytops = addTops(z, gridSize, lengthX, lengthY, spacing, multiline_count, top_distance);
|
||||
result.insert(result.end(), polytops.begin(), polytops.end());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// FillParams has the following useful information:
|
||||
// density <0 .. 1> [proportion of space to fill]
|
||||
// anchor_length [???]
|
||||
// anchor_length_max [???]
|
||||
// dont_connect() [avoid connect lines]
|
||||
// dont_adjust [avoid filling space evenly]
|
||||
// monotonic [fill strictly left to right]
|
||||
// complete [complete each loop]
|
||||
// multiline [number of lines to draw for each pattern line]
|
||||
// complete_top [should the top surfaces of the pattern be filled]
|
||||
|
||||
void Fill3DHoneycomb::_fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
@@ -208,78 +340,62 @@ void Fill3DHoneycomb::_fill_surface_single(
|
||||
ExPolygon expolygon,
|
||||
Polylines &polylines_out)
|
||||
{
|
||||
// no rotation is supported for this infill pattern
|
||||
// Support infill angle
|
||||
auto infill_angle = float(this->angle);
|
||||
if (std::abs(infill_angle) >= EPSILON) expolygon.rotate(-infill_angle);
|
||||
BoundingBox bb = expolygon.contour.bounding_box();
|
||||
|
||||
// Expand the bounding box to avoid artifacts at the edges
|
||||
coord_t expand = 5 * (scale_(this->spacing));
|
||||
bb.offset(expand);
|
||||
// Increase the bounding box outwards to avoid edge clipping artefacts
|
||||
coord_t expandSize = 5. * scale_(this->spacing);
|
||||
bb.offset(expandSize);
|
||||
|
||||
// Adjustment for combining infill setting
|
||||
size_t layersPerSlice = 1;
|
||||
if(thickness_layers > 0){
|
||||
layersPerSlice = thickness_layers;
|
||||
}
|
||||
|
||||
// Note: with equally-scaled X/Y/Z, the pattern will create a vertically-stretched
|
||||
// truncated octahedron; so Z is pre-adjusted first by scaling by sqrt(2)
|
||||
coordf_t zScale = sqrt(2);
|
||||
|
||||
// adjustment to account for the additional distance of octagram curves
|
||||
// note: this only strictly applies for a rectangular area where the total
|
||||
// Z travel distance is a multiple of the spacing... but it should
|
||||
// be at least better than the prevous estimate which assumed straight
|
||||
// lines
|
||||
// Density adjustment to account for the additional distance of
|
||||
// octagram curves. [This only strictly applies for a rectangular
|
||||
// area where the total Z travel distance is a multiple of the
|
||||
// spacing]
|
||||
// = 4 * integrate(func=4*x(sqrt(2) - 1) + 1, from=0, to=0.25)
|
||||
// = (sqrt(2) + 1) / 2 [... I think]
|
||||
// make a first guess at the preferred grid Size
|
||||
coordf_t gridSize = (scale_(this->spacing) * ((zScale + 1.) / 2.) * params.multiline / params.density);
|
||||
|
||||
// This density calculation is incorrect for many values > 25%, possibly
|
||||
// due to quantisation error, so this value is used as a first guess, then the
|
||||
// Z scale is adjusted to make the layer patterns consistent / symmetric
|
||||
// This means that the resultant infill won't be an ideal truncated octahedron,
|
||||
// but it should look better than the equivalent quantised version
|
||||
|
||||
//Orca: uses a fixed layer height to avoid inconsistent bridges and variable layer height artifacts.
|
||||
//coordf_t layerHeight = scale_(thickness_layers);
|
||||
coordf_t layerHeight = scale_(1.0);
|
||||
// ceiling to an integer value of layers per Z
|
||||
// (with a little nudge in case it's close to perfect)
|
||||
// make a first guess at the preferred grid Size (in unscaled units)
|
||||
coordf_t gridSize = (scale_(this->spacing) *
|
||||
((zScale + 1.) / 2.) * params.multiline / params.density);
|
||||
coordf_t layerHeight = scale_(params.layer_height);
|
||||
coordf_t layersPerModule = floor((gridSize * 2) / (zScale * layerHeight) + 0.05);
|
||||
if(params.density > 0.42){ // exact layer pattern for >42% density
|
||||
// If a density over 42% is requested, set an exact layer pattern
|
||||
if((params.density > 0.42) || (layersPerModule < 2)){
|
||||
layersPerModule = 2;
|
||||
// re-adjust the grid size for a partial octahedral path
|
||||
// (scale of 1.1 guessed based on modeling)
|
||||
gridSize = (scale_(this->spacing) * 1.1 * params.multiline / params.density);
|
||||
// re-adjust zScale to make layering consistent
|
||||
zScale = (gridSize * 2) / (layersPerModule * layerHeight);
|
||||
} else {
|
||||
if(layersPerModule < 2){
|
||||
layersPerModule = 2;
|
||||
}
|
||||
// re-adjust zScale to make layering consistent
|
||||
zScale = (gridSize * 2) / (layersPerModule * layerHeight);
|
||||
// re-adjust the grid size to account for the new zScale
|
||||
gridSize = (scale_(this->spacing) * ((zScale + 1.) / 2.) * params.multiline / params.density);
|
||||
// re-calculate layersPerModule and zScale
|
||||
layersPerModule = floor((gridSize * 2) / (zScale * layerHeight) + 0.05);
|
||||
if(layersPerModule < 2){
|
||||
layersPerModule = 2;
|
||||
}
|
||||
zScale = (gridSize * 2) / (layersPerModule * layerHeight);
|
||||
}
|
||||
|
||||
// align bounding box to a multiple of our honeycomb grid module
|
||||
// (a module is 2*$gridSize since one $gridSize half-module is
|
||||
// growing while the other $gridSize half-module is shrinking)
|
||||
bb.merge(align_to_grid(bb.min, Point(gridSize*4, gridSize*4)));
|
||||
// align bounding box to a multiple of the octahedron grid so that
|
||||
// layers with different starting points have matching origins
|
||||
bb.merge(align_to_grid(bb.min, Point(gridSize * 2., gridSize * 2.)));
|
||||
|
||||
// Z adjustment to start at the widest point for the lowest layer
|
||||
coordf_t startOffset = gridSize / 2. + scale_(params.layer_height / 2.);
|
||||
// generate pattern
|
||||
Polylines polylines =
|
||||
makeGrid(
|
||||
scale_(this->z) * zScale,
|
||||
gridSize,
|
||||
bb.size()(0),
|
||||
bb.size()(1),
|
||||
!params.dont_adjust);
|
||||
scale_(this->z) * zScale + startOffset,
|
||||
scale_(this->z - (params.layer_height * params.multiline * layersPerSlice)) * zScale + startOffset,
|
||||
gridSize, bb.size()(0), bb.size()(1),
|
||||
params.infill_complete_top,
|
||||
scale_(this->spacing),
|
||||
params.multiline,
|
||||
layersPerSlice);
|
||||
|
||||
// move pattern in place
|
||||
for (Polyline &pl : polylines){
|
||||
@@ -290,8 +406,8 @@ void Fill3DHoneycomb::_fill_surface_single(
|
||||
smooth_polyline_corners(pl, params.smooth_factor, scaled<double>(params.resolution));
|
||||
}
|
||||
|
||||
// Apply multiline offset if needed
|
||||
multiline_fill(polylines, params, spacing);
|
||||
// Note: multiline fill adjustment is carried out in this code,
|
||||
// rather than using the multiline_fill function
|
||||
|
||||
// clip pattern to boundaries, chain the clipped polylines
|
||||
polylines = intersection_pl(std::move(polylines), to_polygons(expolygon));
|
||||
|
||||
@@ -118,6 +118,7 @@ struct FillParams
|
||||
|
||||
float horiz_move{0.0}; //move infill to get cross zag pattern
|
||||
bool symmetric_infill_y_axis{false};
|
||||
bool infill_complete_top{false};
|
||||
coord_t symmetric_y_axis{0};
|
||||
bool locked_zag{false};
|
||||
float infill_lock_depth{0.0};
|
||||
|
||||
@@ -125,6 +125,7 @@
|
||||
#endif
|
||||
|
||||
#include <Shiny/Shiny.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
using namespace std::literals::string_view_literals;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
#include <ios>
|
||||
#ifdef _WIN32
|
||||
#include <boost/interprocess/sync/file_lock.hpp>
|
||||
#include <boost/nowide/convert.hpp>
|
||||
|
||||
@@ -378,7 +378,7 @@ void Layer::simplify_support_entity_collection(ExtrusionEntityCollection* entity
|
||||
//BBS: method to simplify support path
|
||||
void Layer::simplify_support_path(ExtrusionPath * path)
|
||||
{
|
||||
const auto print_config = this->object()->print()->config();
|
||||
const auto &print_config = this->object()->print()->config();
|
||||
const bool spiral_mode = print_config.spiral_mode;
|
||||
const bool enable_arc_fitting = print_config.enable_arc_fitting;
|
||||
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
|
||||
@@ -393,7 +393,7 @@ void Layer::simplify_support_path(ExtrusionPath * path)
|
||||
//BBS: method to simplify support path
|
||||
void Layer::simplify_support_multi_path(ExtrusionMultiPath* multipath)
|
||||
{
|
||||
const auto print_config = this->object()->print()->config();
|
||||
const auto &print_config = this->object()->print()->config();
|
||||
const bool spiral_mode = print_config.spiral_mode;
|
||||
const bool enable_arc_fitting = print_config.enable_arc_fitting;
|
||||
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
|
||||
@@ -410,7 +410,7 @@ void Layer::simplify_support_multi_path(ExtrusionMultiPath* multipath)
|
||||
//BBS: method to simplify support path
|
||||
void Layer::simplify_support_loop(ExtrusionLoop* loop)
|
||||
{
|
||||
const auto print_config = this->object()->print()->config();
|
||||
const auto &print_config = this->object()->print()->config();
|
||||
const bool spiral_mode = print_config.spiral_mode;
|
||||
const bool enable_arc_fitting = print_config.enable_arc_fitting;
|
||||
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
|
||||
|
||||
@@ -1101,7 +1101,7 @@ void LayerRegion::simplify_entity_collection(ExtrusionEntityCollection* entity_c
|
||||
|
||||
void LayerRegion::simplify_path(ExtrusionPath* path)
|
||||
{
|
||||
const auto print_config = this->layer()->object()->print()->config();
|
||||
const auto &print_config = this->layer()->object()->print()->config();
|
||||
const bool spiral_mode = print_config.spiral_mode;
|
||||
const bool enable_arc_fitting = print_config.enable_arc_fitting;
|
||||
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
|
||||
@@ -1119,7 +1119,7 @@ void LayerRegion::simplify_path(ExtrusionPath* path)
|
||||
|
||||
void LayerRegion::simplify_multi_path(ExtrusionMultiPath* multipath)
|
||||
{
|
||||
const auto print_config = this->layer()->object()->print()->config();
|
||||
const auto &print_config = this->layer()->object()->print()->config();
|
||||
const bool spiral_mode = print_config.spiral_mode;
|
||||
const bool enable_arc_fitting = print_config.enable_arc_fitting;
|
||||
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
|
||||
@@ -1139,7 +1139,7 @@ void LayerRegion::simplify_multi_path(ExtrusionMultiPath* multipath)
|
||||
|
||||
void LayerRegion::simplify_loop(ExtrusionLoop* loop)
|
||||
{
|
||||
const auto print_config = this->layer()->object()->print()->config();
|
||||
const auto &print_config = this->layer()->object()->print()->config();
|
||||
const bool spiral_mode = print_config.spiral_mode;
|
||||
const bool enable_arc_fitting = print_config.enable_arc_fitting;
|
||||
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <system_error>
|
||||
|
||||
#include <fast_float/fast_float.h>
|
||||
#include <clocale>
|
||||
|
||||
// Defined where the floating point std::to_chars can be called, which with Apple's libc++ runtime is from macOS 13.3.
|
||||
#if defined(_LIBCPP_VERSION)
|
||||
|
||||
@@ -1209,6 +1209,7 @@ static std::vector<std::string> s_Preset_print_options{
|
||||
"infill_lock_depth",
|
||||
"skin_infill_depth",
|
||||
"skin_infill_density",
|
||||
"infill_complete_top",
|
||||
"align_infill_direction_to_model",
|
||||
"extra_solid_infills",
|
||||
"center_of_surface_pattern",
|
||||
|
||||
@@ -4664,6 +4664,13 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("infill_complete_top", coBool);
|
||||
def->label = L("Fill pattern tops");
|
||||
def->category = L("Strength");
|
||||
def->tooltip = L("Choose this option if you want to completely fill in the tops of the infill pattern");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
// Orca: max layer height for combined infill
|
||||
def = this->add("infill_combination_max_layer_height", coFloatOrPercent);
|
||||
def->label = L("Infill combination - Max layer height");
|
||||
|
||||
@@ -1425,6 +1425,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloat, bottom_layer_direction))
|
||||
((ConfigOptionString, solid_infill_rotate_template))
|
||||
((ConfigOptionBool, symmetric_infill_y_axis))
|
||||
((ConfigOptionBool, infill_complete_top))
|
||||
((ConfigOptionFloat, infill_shift_step))
|
||||
((ConfigOptionString, sparse_infill_rotate_template))
|
||||
((ConfigOptionPercent, sparse_infill_density))
|
||||
|
||||
@@ -3582,14 +3582,14 @@ void PrintObject::bridge_over_infill()
|
||||
const bool turning_pattern = region_config.sparse_infill_pattern == ipHilbertCurve ||
|
||||
region_config.sparse_infill_pattern == ipOctagramSpiral;
|
||||
const Flow &flow = candidate.region->bridging_flow(frSolidInfill, true);
|
||||
Polygons area_to_be_bridge = expand(candidate.new_polys, flow.scaled_spacing());
|
||||
area_to_be_bridge = intersection(area_to_be_bridge, deep_infill_area);
|
||||
|
||||
area_to_be_bridge.erase(std::remove_if(area_to_be_bridge.begin(), area_to_be_bridge.end(),
|
||||
[internal_unsupported_area](const Polygon &p) {
|
||||
return intersection({p}, internal_unsupported_area).empty();
|
||||
ExPolygons bridge_components = intersection_ex(expand(candidate.new_polys, flow.scaled_spacing()), deep_infill_area);
|
||||
// Orca: Filter whole bridge areas so their holes remain holes.
|
||||
bridge_components.erase(std::remove_if(bridge_components.begin(), bridge_components.end(),
|
||||
[&internal_unsupported_area](const ExPolygon &component) {
|
||||
return intersection_ex(component, internal_unsupported_area).empty();
|
||||
}),
|
||||
area_to_be_bridge.end());
|
||||
bridge_components.end());
|
||||
Polygons area_to_be_bridge = to_polygons(std::move(bridge_components));
|
||||
|
||||
Polygons limiting_area = union_(area_to_be_bridge, expansion_area);
|
||||
|
||||
|
||||
@@ -2166,7 +2166,7 @@ Polygons TreeSupport::get_trim_support_regions(
|
||||
static const double no_overlap_xy_gap = 0.2f;
|
||||
double gap_xy_scaled = scale_(gap_xy);
|
||||
SupportLayer& support_layer = *support_layer_ptr;
|
||||
auto m_print_config = object.print()->config();
|
||||
const PrintConfig& print_config = object.print()->config();
|
||||
|
||||
size_t idx_object_layer_overlapping = size_t(-1);
|
||||
|
||||
@@ -2213,7 +2213,7 @@ Polygons TreeSupport::get_trim_support_regions(
|
||||
const Layer& object_layer = *object.layers()[i];
|
||||
bool some_region_overlaps = false;
|
||||
for (LayerRegion* region : object_layer.regions()) {
|
||||
coordf_t bridging_height = region->region().bridging_height_avg(m_print_config);
|
||||
coordf_t bridging_height = region->region().bridging_height_avg(print_config);
|
||||
if (object_layer.print_z - bridging_height > support_layer.print_z + gap_extra_above - EPSILON)
|
||||
break;
|
||||
some_region_overlaps = true;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <tbb/task_arena.h>
|
||||
|
||||
#include "Thread.hpp"
|
||||
#include <cstring>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -119,6 +119,7 @@
|
||||
// We are using quite an old TBB 2017 U7, which does not support global control API officially.
|
||||
// Before we update our build servers, let's use the old API, which is deprecated in up to date TBB.
|
||||
#include <tbb/tbb.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace boost::posix_time { class ptime; }
|
||||
#if ! defined(TBB_VERSION_MAJOR)
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
#include "Widgets/Label.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include <wx/dcgraph.h>
|
||||
#include <wx/dcmemory.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
|
||||
@@ -60,6 +60,9 @@
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "slic3r/GUI/PartPlate.hpp"
|
||||
#include "slic3r/Utils/PrintHost.hpp"
|
||||
#ifdef _WIN32
|
||||
#include <excpt.h>
|
||||
#endif
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -825,6 +825,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in
|
||||
bool have_infill = config->option<ConfigOptionPercent>("sparse_infill_density")->value > 0;
|
||||
// sparse_infill_filament_id uses the same logic as in Print::extruders()
|
||||
for (auto el : { "sparse_infill_pattern", "infill_combination", "fill_multiline","infill_direction",
|
||||
"infill_complete_top",
|
||||
"minimum_sparse_infill_area", "sparse_infill_filament_id","infill_shift_step","sparse_infill_rotate_template","symmetric_infill_y_axis"})
|
||||
toggle_line(el, have_infill);
|
||||
|
||||
@@ -879,6 +880,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in
|
||||
|
||||
toggle_line("symmetric_infill_y_axis", is_zig_zag || is_cross_zag || is_locked_zig);
|
||||
|
||||
bool is_3Dhoneycomb = config->option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->value == InfillPattern::ip3DHoneycomb;
|
||||
toggle_line("infill_complete_top", have_infill && is_3Dhoneycomb);
|
||||
|
||||
bool has_spiral_vase = config->opt_bool("spiral_mode");
|
||||
toggle_line("spiral_mode_smooth", has_spiral_vase);
|
||||
toggle_line("spiral_mode_max_xy_smoothing", has_spiral_vase && config->opt_bool("spiral_mode_smooth"));
|
||||
@@ -888,7 +892,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in
|
||||
bool has_top_shell = has_top_shell_layers && config->option<ConfigOptionPercent>("top_surface_density")->value > 0;
|
||||
bool has_bottom_shell = config->opt_int("bottom_shell_layers") > 0;
|
||||
bool has_solid_infill = has_top_shell_layers || has_bottom_shell;
|
||||
toggle_line("sparse_infill_smooth_factor", is_smoothable_infill_pattern(pattern, config->opt_int("fill_multiline")));
|
||||
toggle_line("sparse_infill_smooth_factor", have_infill && is_smoothable_infill_pattern(pattern, config->opt_int("fill_multiline")));
|
||||
toggle_field("top_surface_pattern", has_top_shell);
|
||||
toggle_field("bottom_surface_pattern", has_bottom_shell);
|
||||
toggle_field("top_surface_density", has_top_shell_layers);
|
||||
|
||||
@@ -53,6 +53,8 @@ wxString get_string_from_enum(const std::string& opt_key, const DynamicPrintConf
|
||||
}
|
||||
return _L("Undefined");
|
||||
}
|
||||
if (val < 0 || val >= int(names.size()))
|
||||
return _L("Undefined");
|
||||
return from_u8(_utf8(names[val]));
|
||||
}
|
||||
|
||||
@@ -215,6 +217,8 @@ wxString get_string_value(const std::string& opt_key, const DynamicPrintConfig&
|
||||
;
|
||||
}
|
||||
case coEnums: {
|
||||
if (!opt_vector || opt_idx >= opt_vector->size())
|
||||
return _L("Undefined");
|
||||
return get_string_from_enum(pure_key, config,
|
||||
pure_key == "top_surface_pattern" ||
|
||||
pure_key == "bottom_surface_pattern" ||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "GUI.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include "Widgets/Button.hpp"
|
||||
#include <wx/types.h>
|
||||
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoBase.hpp"
|
||||
#include <wx/arrstr.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <wx/event.h>
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Widgets/DropDown.hpp"
|
||||
#include <wx/dvrenderers.h>
|
||||
#ifdef wxHAS_GENERIC_DATAVIEWCTRL
|
||||
#include "wx/generic/private/markuptext.h"
|
||||
#include "wx/generic/private/rowheightcache.h"
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
|
||||
#include "../Utils/ColorSpaceConvert.hpp"
|
||||
#include "../Utils/NetworkAgentFactory.hpp"
|
||||
#include <wx/sizer.h>
|
||||
#ifdef __WXOSX__
|
||||
#define wxOSX true
|
||||
#else
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/button.h>
|
||||
#include <cstddef>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
@@ -257,6 +257,11 @@
|
||||
#include "slic3r/GUI/wxExtensions.hpp"
|
||||
#include "slic3r/plugin/host/PluginPages.hpp"
|
||||
#include <wx/defs.h>
|
||||
#include "slic3r/GUI/Widgets/WebView.hpp"
|
||||
#include <cwchar>
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/itemattr.h>
|
||||
#include <wx/version.h>
|
||||
|
||||
//#ifdef WIN32
|
||||
//#include "BaseException.h"
|
||||
@@ -285,6 +290,7 @@ typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS2)(
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include <boost/dll/runtime_symbol_info.hpp>
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "slic3r/GUI/Gizmos/GLGizmosManager.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/Selection.hpp"
|
||||
#include "slic3r/GUI/GUI_Utils.hpp"
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "libslic3r/TriangleSelector.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/GUI_Utils.hpp"
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/PartPlate.hpp"
|
||||
#include "slic3r/GUI/Selection.hpp"
|
||||
#include "slic3r/GUI/GUI_Utils.hpp"
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "libslic3r/Color.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
#include <memory>
|
||||
#include "slic3r/GUI/GUI_Utils.hpp"
|
||||
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <cstddef>
|
||||
#include <wx/app.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "slic3r/GUI/GUI_Utils.hpp"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <wx/msw/winundef.h>
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "libslic3r/TriangleMesh.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/GUI_Utils.hpp"
|
||||
|
||||
#define MAX_NUM 9999.99
|
||||
#define MAX_SIZE std::string_view{"9999.99"}
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <errno.h>
|
||||
#include <optional>
|
||||
#include <cstdint>
|
||||
#include <cwchar>
|
||||
#include <memory>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <strsafe.h>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <string>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
#if __linux__
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
@@ -150,6 +150,9 @@
|
||||
#include "slic3r/plugin/host/PluginPages.hpp"
|
||||
#include "slic3r/Utils/NetworkAgent.hpp"
|
||||
#include <wx/defs.h>
|
||||
#include <cassert>
|
||||
#include <wx/display.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
|
||||
#include <wx/clipbrd.h>
|
||||
#include "wx/evtloop.h"
|
||||
#include <boost/nowide/convert.hpp>
|
||||
|
||||
class wxImage;
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include "I18N.hpp"
|
||||
|
||||
#include <bitset>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
//unofficial linux lib
|
||||
#ifdef HAVE_SPNAV
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <wx/dcgraph.h>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "slic3r/GUI/MsgDialog.hpp"
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <wx/dcgraph.h>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <wx/timer.h>
|
||||
|
||||
#include "DeviceCore/DevManager.h"
|
||||
#include <wx/dcgraph.h>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
@@ -42,6 +42,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <cassert>
|
||||
#include <cwchar>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
#include "wxExtensions.hpp"
|
||||
|
||||
#include "DeviceCore/DevManager.h"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp"
|
||||
|
||||
// A workaround for a set of issues related to text fitting into gtk widgets:
|
||||
#if defined(__WXGTK20__) || defined(__WXGTK3__)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <wx/string.h>
|
||||
#include <wx/webview.h>
|
||||
#include <wx/utils.h>
|
||||
#include <wx/buffer.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <system_error>
|
||||
#include <wx/event.h>
|
||||
#include <utility>
|
||||
#include <cwchar>
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
// Custom wxWidget events
|
||||
#include "Event.hpp"
|
||||
#include <atomic>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include "BindDialog.hpp"
|
||||
|
||||
#include "DeviceCore/DevManager.h"
|
||||
#include <wx/textctrl.h>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
#include "slic3r/GUI/Widgets/CheckBox.hpp"
|
||||
#include "slic3r/GUI/wxExtensions.hpp"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <wx/dcgraph.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
|
||||
@@ -73,6 +73,9 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include <cstdlib>
|
||||
#include <iomanip>
|
||||
|
||||
class wxWindow;
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@
|
||||
#include "SafetyOptionsDialog.hpp"
|
||||
|
||||
#include "ThermalPreconditioningDialog.hpp"
|
||||
#include <wx/dcgraph.h>
|
||||
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
@@ -117,6 +117,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <unordered_set>
|
||||
#include "slic3r/GUI/GUI_Utils.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -2935,6 +2936,7 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("skin_infill_line_width", "strength_settings_patterns#locked-zag");
|
||||
optgroup->append_single_option_line("skeleton_infill_line_width", "strength_settings_patterns#locked-zag");
|
||||
optgroup->append_single_option_line("symmetric_infill_y_axis", "strength_settings_infill#symmetric-infill-y-axis");
|
||||
optgroup->append_single_option_line("infill_complete_top", "strength_settings_infill#infill-complete-top");
|
||||
optgroup->append_single_option_line("infill_shift_step", "strength_settings_patterns#cross-hatch");
|
||||
optgroup->append_single_option_line("lateral_lattice_angle_1", "strength_settings_patterns#lateral-lattice");
|
||||
optgroup->append_single_option_line("lateral_lattice_angle_2", "strength_settings_patterns#lateral-lattice");
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <wx/window.h>
|
||||
#include <wx/busycursor.h>
|
||||
|
||||
static constexpr const char* DEFAULT_VIRTUAL_FILAMENT_BASIC_TYPE = "PLA Basic";
|
||||
static constexpr const char* DEFAULT_VIRTUAL_FILAMENT_SHORT_TYPE = "PLA";
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <wx/webview.h>
|
||||
#include <wx/utils.h>
|
||||
#include <wx/window.h>
|
||||
#include <wx/infobar.h>
|
||||
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <wx/peninfobase.h>
|
||||
#include <algorithm>
|
||||
#include "slic3r/GUI/Widgets/StateColor.hpp"
|
||||
#include <wx/dcgraph.h>
|
||||
|
||||
LabeledStaticBox::LabeledStaticBox()
|
||||
: state_handler(this)
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#include "ProgressDialog.hpp"
|
||||
#include "wx/evtloop.h"
|
||||
#include "Label.hpp"
|
||||
#include <wx/event.h>
|
||||
#include <wx/gauge.h>
|
||||
#include <wx/sizer.h>
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#include "slic3r/GUI/Widgets/StateColor.hpp"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/colour.h>
|
||||
|
||||
#ifdef __WXMSW__
|
||||
class TextCtrl : public wxTextCtrl
|
||||
|
||||
@@ -35,6 +35,12 @@
|
||||
#include <wx/filename.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <ios>
|
||||
#include <string>
|
||||
#include <wx/versioninfo.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
#if defined(__WIN32__) || defined(__WXMAC__)
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
#include <Shlwapi.h>
|
||||
#include "windowsx.h"
|
||||
#include "stdlib.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cwchar>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <cmath>
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <string.h>
|
||||
|
||||
template <typename T, typename T1, typename T2>
|
||||
constexpr T RVA2VA(T1 base, T2 rva)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <unordered_set>
|
||||
#include <mutex>
|
||||
#include <cwchar>
|
||||
|
||||
enum IMMERSIVE_HC_CACHE_MODE
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <wx/string.h>
|
||||
#include <wx/buffer.h>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "FilamentBitmapUtils.hpp"
|
||||
#include "../Utils/ColorSpaceConvert.hpp"
|
||||
#include "libslic3r_version.h"
|
||||
#include <map>
|
||||
#ifndef __linux__
|
||||
// msw_menuitem_bitmaps is used for MSW and OSX
|
||||
static std::map<int, std::string> msw_menuitem_bitmaps;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/mediactrl.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/image.h>
|
||||
extern "C" {
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/log.h>
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#include <utility>
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "slic3r/Utils/FileTransferUtils.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <cwchar>
|
||||
|
||||
#if !defined(_MSC_VER) && !defined(_WIN32)
|
||||
#include <dlfcn.h>
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
#include "Bonjour.hpp"
|
||||
#include "slic3r/GUI/BonjourDialog.hpp"
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
#include "Bonjour.hpp"
|
||||
#include "slic3r/GUI/BonjourDialog.hpp"
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include "libslic3r/InstanceLock.hpp"
|
||||
#include "test_utils.hpp"
|
||||
#include <ios>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <boost/interprocess/sync/file_lock.hpp>
|
||||
|
||||
@@ -2,6 +2,7 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
|
||||
add_executable(${_TEST_NAME}_tests
|
||||
${_TEST_NAME}_tests_main.cpp
|
||||
test_bambu_filament_ids.cpp
|
||||
test_config_value_formatter.cpp
|
||||
test_creality_cfs_match.cpp
|
||||
test_dev_mapping.cpp
|
||||
test_filament_bitmap_utils.cpp
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "slic3r/GUI/ConfigValueFormatter.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
using namespace Slic3r::GUI;
|
||||
|
||||
TEST_CASE("An enum vector index past the end of the vector reads as undefined", "[ConfigValueFormatter][Regression]")
|
||||
{
|
||||
const std::string key = "filament_retract_lift_enforce";
|
||||
const ConfigOptionDef* def = print_config_def.get(key);
|
||||
DynamicPrintConfig config;
|
||||
config.set_key_value(key, new ConfigOptionEnumsGenericNullable(def->enum_keys_map, 1, ConfigOptionEnumsGenericNullable::nil_value()));
|
||||
|
||||
CHECK(get_string_value(key + "#1", config) == "Undefined");
|
||||
}
|
||||
|
||||
TEST_CASE("An enum vector index inside the vector reads as its label", "[ConfigValueFormatter]")
|
||||
{
|
||||
const std::string key = "filament_retract_lift_enforce";
|
||||
const ConfigOptionDef* def = print_config_def.get(key);
|
||||
DynamicPrintConfig config;
|
||||
config.set_key_value(key, new ConfigOptionEnumsGenericNullable(def->enum_keys_map, 1, def->enum_keys_map->at("Top Only")));
|
||||
|
||||
CHECK(get_string_value(key + "#0", config).utf8_string() == "Top Only");
|
||||
}
|
||||
|
||||
TEST_CASE("An enum value outside the label list reads as undefined", "[ConfigValueFormatter]")
|
||||
{
|
||||
const std::string key = "filament_retract_lift_enforce";
|
||||
const ConfigOptionDef* def = print_config_def.get(key);
|
||||
DynamicPrintConfig config;
|
||||
config.set_key_value(key, new ConfigOptionEnumsGenericNullable(def->enum_keys_map, 1, int(def->enum_labels.size())));
|
||||
|
||||
CHECK(get_string_value(key + "#0", config) == "Undefined");
|
||||
}
|
||||
Reference in New Issue
Block a user