Changeset View
Changeset View
Standalone View
Standalone View
plugins/generators/simplexnoise/simplexnoisegenerator.cpp
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | * KDE. Krita Project. | ||||
3 | * | ||||
4 | * Copyright (c) 2019 Eoin O'Neill <eoinoneill1991@gmail.com> | ||||
5 | * Copyright (c) 2019 Emmet O'Neill <emmetoneill.pdx@gmail.com> | ||||
6 | * | ||||
7 | * This program is free software; you can redistribute it and/or modify | ||||
8 | * it under the terms of the GNU General Public License as published by | ||||
9 | * the Free Software Foundation; either version 2 of the License, or | ||||
10 | * (at your option) any later version. | ||||
11 | * | ||||
12 | * This program is distributed in the hope that it will be useful, | ||||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
15 | * GNU General Public License for more details. | ||||
16 | * | ||||
17 | * You should have received a copy of the GNU General Public License | ||||
18 | * along with this program; if not, write to the Free Software | ||||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
20 | */ | ||||
21 | | ||||
22 | #include "simplexnoisegenerator.h" | ||||
23 | #include <stdlib.h> | ||||
24 | #include <vector> | ||||
25 | #include <math.h> | ||||
26 | | ||||
27 | #include <QPoint> | ||||
28 | | ||||
29 | #include <kis_debug.h> | ||||
30 | | ||||
31 | #include <kpluginfactory.h> | ||||
32 | #include <klocalizedstring.h> | ||||
33 | | ||||
34 | #include <KoUpdater.h> | ||||
35 | | ||||
36 | #include <KoMixColorsOp.h> | ||||
37 | #include <kis_image.h> | ||||
38 | #include <kis_paint_device.h> | ||||
39 | #include <kis_layer.h> | ||||
40 | #include <generator/kis_generator_registry.h> | ||||
41 | #include <kis_global.h> | ||||
42 | #include <kis_random_generator.h> | ||||
43 | #include <kis_selection.h> | ||||
44 | #include <kis_types.h> | ||||
45 | #include <filter/kis_filter_configuration.h> | ||||
46 | #include <kis_processing_information.h> | ||||
47 | #include <QCryptographicHash> | ||||
48 | | ||||
49 | #include "kis_wdg_simplex_noise.h" | ||||
50 | #include "c-open-simplex/open-simplex-noise.h" | ||||
51 | #include "ui_wdgsimplexnoiseoptions.h" | ||||
52 | #include <KisSequentialIteratorProgress.h> | ||||
53 | | ||||
54 | | ||||
55 | K_PLUGIN_FACTORY_WITH_JSON(KritaSimplexNoiseGeneratorFactory, "kritasimplexnoisegenerator.json", registerPlugin<KisSimplexNoiseGeneratorHandle>();) | ||||
56 | | ||||
57 | KisSimplexNoiseGeneratorHandle::KisSimplexNoiseGeneratorHandle(QObject *parent, const QVariantList &) | ||||
58 | : QObject(parent) | ||||
59 | { | ||||
60 | KisGeneratorRegistry::instance()->add(new KisSimplexNoiseGenerator()); | ||||
61 | | ||||
62 | } | ||||
63 | | ||||
64 | KisSimplexNoiseGeneratorHandle::~KisSimplexNoiseGeneratorHandle() | ||||
65 | { | ||||
66 | } | ||||
67 | | ||||
68 | KisSimplexNoiseGenerator::KisSimplexNoiseGenerator() : KisGenerator(id(), KoID("basic"), i18n("&Simplex Noise...")) | ||||
69 | { | ||||
70 | setColorSpaceIndependence(FULLY_INDEPENDENT); | ||||
71 | setSupportsPainting(true); | ||||
72 | } | ||||
73 | | ||||
74 | void KisSimplexNoiseGenerator::generate(KisProcessingInformation dst, const QSize &size, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const | ||||
75 | { | ||||
76 | KisPaintDeviceSP device = dst.paintDevice(); | ||||
77 | Q_ASSERT(!device.isNull()); | ||||
78 | | ||||
79 | osn_context *noise_context; | ||||
80 | | ||||
81 | QRect bounds = QRect(dst.topLeft(), size); | ||||
82 | const KoColorSpace * cs = device->colorSpace(); | ||||
83 | KisSequentialIteratorProgress it(device, bounds, progressUpdater); | ||||
84 | | ||||
85 | QVariant property; | ||||
86 | | ||||
87 | const uint default_seed = (config->getProperty("seed", property)) ? property.toUInt() : 0; | ||||
88 | const QString custom_seed_string = (config->getProperty("custom_seed_string", property)) ? property.toString() : ""; | ||||
89 | const bool use_custom_seed = !custom_seed_string.trimmed().isEmpty(); | ||||
90 | | ||||
91 | const uint seed = use_custom_seed ? seedFromString(custom_seed_string) : default_seed; | ||||
92 | open_simplex_noise(seed, &noise_context); | ||||
93 | | ||||
94 | double frequency = (config && config->getProperty("frequency", property)) ? property.toDouble() : 25.0; | ||||
95 | double ratio_x = (config && config->getProperty("ratio_x", property)) ? property.toDouble() : 1.0; | ||||
96 | double ratio_y = (config && config->getProperty("ratio_y", property)) ? property.toDouble() : 1.0; | ||||
97 | | ||||
98 | bool looping = (config && config->getProperty("looping", property)) ? property.toBool() : false; | ||||
99 | | ||||
100 | if( looping ){ | ||||
101 | float major_radius = 0.5f * frequency * ratio_x; | ||||
102 | float minor_radius = 0.5f * frequency * ratio_y; | ||||
103 | while(it.nextPixel()){ | ||||
104 | double x_phase = (double)it.x() / (double)bounds.width() * M_PI * 2; | ||||
105 | double y_phase = (double)it.y() / (double)(bounds.height()) * M_PI * 2; | ||||
106 | double x_coordinate = major_radius * map_range(cos(x_phase), -1.0, 1.0, 0.0, 1.0); | ||||
107 | double y_coordinate = major_radius * map_range(sin(x_phase), -1.0, 1.0, 0.0, 1.0); | ||||
108 | double z_coordinate = minor_radius * map_range(cos(y_phase), -1.0, 1.0, 0.0, 1.0); | ||||
109 | double w_coordinate = minor_radius * map_range(sin(y_phase), -1.0, 1.0, 0.0, 1.0); | ||||
110 | double value = open_simplex_noise4(noise_context, x_coordinate, y_coordinate, z_coordinate, w_coordinate); | ||||
111 | value = map_range(value, -1.0, 1.0, 0.0, 255.0); | ||||
112 | QColor color = qRgb(static_cast<int>(value), | ||||
113 | static_cast<int>(value), | ||||
114 | static_cast<int>(value)); | ||||
115 | cs->fromQColor(color, it.rawData()); | ||||
116 | } | ||||
117 | } else { | ||||
118 | while(it.nextPixel()){ | ||||
119 | double x_phase = (double)it.x() / (double)(bounds.width()) * ratio_x; | ||||
120 | double y_phase = (double)it.y() / (double)(bounds.height()) * ratio_y; | ||||
121 | double value = open_simplex_noise4(noise_context, x_phase * frequency, y_phase * frequency, x_phase * frequency, y_phase * frequency); | ||||
122 | value = map_range(value, -1.0, 1.0, 0.0, 255.0); | ||||
123 | QColor color = qRgb(static_cast<int>(value), | ||||
124 | static_cast<int>(value), | ||||
125 | static_cast<int>(value)); | ||||
126 | cs->fromQColor(color, it.rawData()); | ||||
127 | } | ||||
128 | } | ||||
129 | | ||||
130 | open_simplex_noise_free(noise_context); | ||||
131 | } | ||||
132 | | ||||
133 | KisFilterConfigurationSP KisSimplexNoiseGenerator::factoryConfiguration() const | ||||
134 | { | ||||
135 | KisFilterConfigurationSP config = new KisFilterConfiguration("simplex_noise", 1); | ||||
136 | config->setProperty("looping", false); | ||||
137 | config->setProperty("frequency", 25.0); | ||||
138 | uint seed = static_cast<uint>(rand()); | ||||
139 | config->setProperty("seed", seed); | ||||
140 | config->setProperty("custom_seed_string", ""); | ||||
141 | config->setProperty("ratio_x", 1.0f); | ||||
142 | config->setProperty("ratio_y", 1.0f); | ||||
143 | return config; | ||||
144 | } | ||||
145 | | ||||
146 | KisConfigWidget * KisSimplexNoiseGenerator::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev) const | ||||
147 | { | ||||
148 | Q_UNUSED(dev); | ||||
149 | return new KisWdgSimplexNoise((KisFilter*)this, (QWidget*)parent); | ||||
150 | } | ||||
151 | | ||||
152 | | ||||
153 | uint KisSimplexNoiseGenerator::seedFromString(const QString &string) const | ||||
154 | { | ||||
155 | QByteArray bytes = QCryptographicHash::hash(string.toUtf8(),QCryptographicHash::Md5); | ||||
156 | uint hash = 0; | ||||
157 | for( int index = 0; index < bytes.length(); index++){ | ||||
158 | hash += rotateLeft(bytes[index], index % 32); | ||||
159 | } | ||||
160 | return hash; | ||||
161 | } | ||||
162 | | ||||
163 | quint64 KisSimplexNoiseGenerator::rotateLeft(const quint64 input, uint shift) const | ||||
164 | { | ||||
165 | return (input << shift)|(input >> (64 - shift)); | ||||
166 | } | ||||
167 | | ||||
168 | #include "simplexnoisegenerator.moc" | ||||
169 | |