forked from Ultimaker/CuraEngine
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathSierpinskiFillProvider.cpp
92 lines (78 loc) · 2.9 KB
/
SierpinskiFillProvider.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
80
81
82
83
84
85
86
87
88
89
90
91
92
//Copyright (C) 2017 Tim Kuipers
//Copyright (c) 2018 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.
#include "ImageBasedDensityProvider.h"
#include "UniformDensityProvider.h"
#include "SierpinskiFillProvider.h"
#include "../utils/AABB3D.h"
#include "../utils/logoutput.h"
#include "../utils/math.h"
#include "../utils/polygon.h"
namespace cura
{
constexpr bool SierpinskiFillProvider::get_constructor;
constexpr bool SierpinskiFillProvider::use_dithering;
SierpinskiFillProvider::SierpinskiFillProvider(const AABB3D aabb_3d, coord_t min_line_distance, const coord_t line_width)
: fractal_config(getFractalConfig(aabb_3d, min_line_distance))
, density_provider(new UniformDensityProvider((float)line_width / min_line_distance))
, fill_pattern_for_all_layers(get_constructor, *density_provider, fractal_config.aabb, fractal_config.depth, line_width, use_dithering)
{
}
SierpinskiFillProvider::SierpinskiFillProvider(const AABB3D aabb_3d, coord_t min_line_distance, coord_t line_width, std::string cross_subdisivion_spec_image_file)
: fractal_config(getFractalConfig(aabb_3d, min_line_distance))
, density_provider(new ImageBasedDensityProvider(cross_subdisivion_spec_image_file, aabb_3d.flatten()))
, fill_pattern_for_all_layers(get_constructor, *density_provider, fractal_config.aabb, fractal_config.depth, line_width, use_dithering)
{
}
Polygon SierpinskiFillProvider::generate(EFillMethod pattern, coord_t z, coord_t line_width, coord_t pocket_size) const
{
if (fill_pattern_for_all_layers)
{
if (pattern == EFillMethod::CROSS_3D)
{
return fill_pattern_for_all_layers->generateCross(z, line_width / 2, pocket_size);
}
else
{
return fill_pattern_for_all_layers->generateCross();
}
}
else
{
Polygon ret;
logError("Different density sierpinski fill for different layers is not implemented yet!\n");
std::exit(-1);
return ret;
}
}
SierpinskiFillProvider::~SierpinskiFillProvider()
{
if (density_provider)
{
delete density_provider;
}
}
SierpinskiFillProvider::FractalConfig SierpinskiFillProvider::getFractalConfig(const AABB3D aabb_3d, coord_t min_line_distance)
{
AABB model_aabb = aabb_3d.flatten();
Point model_aabb_size = model_aabb.max - model_aabb.min;
coord_t max_side_length = std::max(model_aabb_size.X, model_aabb_size.Y);
Point model_middle = model_aabb.getMiddle();
int depth = 0;
coord_t aabb_size = min_line_distance;
while (aabb_size < max_side_length)
{
aabb_size *= 2;
depth += 2;
}
const float half_sqrt2 = .5 * sqrt2;
if (aabb_size * half_sqrt2 >= max_side_length)
{
aabb_size *= half_sqrt2;
depth--;
}
Point radius(aabb_size / 2, aabb_size / 2);
AABB aabb(model_middle - radius, model_middle + radius);
return FractalConfig{depth, aabb};
}
}; // namespace cura