forked from Ultimaker/CuraEngine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
infill.cpp
79 lines (70 loc) · 2.85 KB
/
infill.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include "infill.h"
void generateConcentricInfill(Polygons outline, Polygons& result, int offsets[], int offsetsSize)
{
int step = 0;
while(1)
{
for(unsigned int polygonNr=0; polygonNr<outline.size(); polygonNr++)
result.add(outline[polygonNr]);
outline = outline.offset(-offsets[step]);
if (outline.size() < 1)
break;
step = (step + 1) % offsetsSize;
}
}
int compare_int64_t(const void* a, const void* b)
{
int64_t n = (*(int64_t*)a) - (*(int64_t*)b);
if (n < 0) return -1;
if (n > 0) return 1;
return 0;
}
void generateLineInfill(const Polygons& in_outline, Polygons& result, int extrusionWidth, int lineSpacing, int infillOverlap, double rotation)
{
Polygons outline = in_outline.offset(extrusionWidth * infillOverlap / 100);
PointMatrix matrix(rotation);
outline.applyMatrix(matrix);
AABB boundary(outline);
boundary.min.X = ((boundary.min.X / lineSpacing) - 1) * lineSpacing;
int lineCount = (boundary.max.X - boundary.min.X + (lineSpacing - 1)) / lineSpacing;
vector<vector<int64_t> > cutList;
for(int n=0; n<lineCount; n++)
cutList.push_back(vector<int64_t>());
for(unsigned int polyNr=0; polyNr < outline.size(); polyNr++)
{
Point p1 = outline[polyNr][outline[polyNr].size()-1];
for(unsigned int i=0; i < outline[polyNr].size(); i++)
{
Point p0 = outline[polyNr][i];
int idx0 = (p0.X - boundary.min.X) / lineSpacing;
int idx1 = (p1.X - boundary.min.X) / lineSpacing;
int64_t xMin = p0.X, xMax = p1.X;
if (p0.X > p1.X) { xMin = p1.X; xMax = p0.X; }
if (idx0 > idx1) { int tmp = idx0; idx0 = idx1; idx1 = tmp; }
for(int idx = idx0; idx<=idx1; idx++)
{
int x = (idx * lineSpacing) + boundary.min.X + lineSpacing / 2;
if (x < xMin) continue;
if (x >= xMax) continue;
int y = p0.Y + (p1.Y - p0.Y) * (x - p0.X) / (p1.X - p0.X);
cutList[idx].push_back(y);
}
p1 = p0;
}
}
int idx = 0;
for(int64_t x = boundary.min.X + lineSpacing / 2; x < boundary.max.X; x += lineSpacing)
{
qsort(cutList[idx].data(), cutList[idx].size(), sizeof(int64_t), compare_int64_t);
for(unsigned int i = 0; i + 1 < cutList[idx].size(); i+=2)
{
if (cutList[idx][i+1] - cutList[idx][i] < extrusionWidth / 5)
continue;
PolygonRef p = result.newPoly();
p.add(matrix.unapply(Point(x, cutList[idx][i])));
p.add(matrix.unapply(Point(x, cutList[idx][i+1])));
}
idx += 1;
}
}