Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
geom-pathvector_nodesatellites.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
/*
5 * Authors: see git history
6 * Jabiertxof
7 * Nathan Hurst
8 * Johan Engelen
9 * Josh Andler
10 * suv
11 * Mc-
12 * Liam P. White
13 * Krzysztof KosiƄski
14 * This code is in public domain
15 *
16 * Copyright (C) 2018 Authors
17 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
18 */
19
21#include <helper/geom.h>
22
23#include "util/units.h"
24
29
34
39
41{
42 _nodesatellites = nodesatellites;
43}
44
46{
47 size_t counter = 0;
48 for (auto &_nodesatellite : _nodesatellites) {
49 counter += _nodesatellite.size();
50 }
51 return counter;
52}
53
54std::pair<size_t, size_t> PathVectorNodeSatellites::getIndexData(size_t index)
55{
56 size_t counter = 0;
57 for (size_t i = 0; i < _nodesatellites.size(); ++i) {
58 for (size_t j = 0; j < _nodesatellites[i].size(); ++j) {
59 if (index == counter) {
60 return std::make_pair(i,j);
61 }
62 counter++;
63 }
64 }
65 return std::make_pair(0,0);
66}
67
68void PathVectorNodeSatellites::setSelected(std::vector<size_t> selected)
69{
70 size_t counter = 0;
71 for (auto &_nodesatellite : _nodesatellites) {
72 for (auto &j : _nodesatellite) {
73 if (find (selected.begin(), selected.end(), counter) != selected.end()) {
74 j.setSelected(true);
75 } else {
76 j.setSelected(false);
77 }
78 counter++;
79 }
80 }
81}
82
83void PathVectorNodeSatellites::updateSteps(size_t steps, bool apply_no_radius, bool apply_with_radius,
84 bool only_selected)
85{
86 for (auto &_nodesatellite : _nodesatellites) {
87 for (auto &j : _nodesatellite) {
88 if ((!apply_no_radius && j.amount == 0) ||
89 (!apply_with_radius && j.amount != 0))
90 {
91 continue;
92 }
93 if (only_selected) {
94 if (j.selected) {
95 j.steps = steps;
96 }
97 } else {
98 j.steps = steps;
99 }
100 }
101 }
102}
103
104void PathVectorNodeSatellites::updateAmount(double radius, bool apply_no_radius, bool apply_with_radius,
105 bool only_selected, bool use_knot_distance, bool flexible)
106{
107 double power = 0;
108 if (!flexible) {
109 power = radius;
110 } else {
111 power = radius / 100;
112 }
113 for (size_t i = 0; i < _nodesatellites.size(); ++i) {
114 for (size_t j = 0; j < _nodesatellites[i].size(); ++j) {
115 std::optional<size_t> previous_index = std::nullopt;
116 if (j == 0 && _pathvector[i].closed()) {
117 previous_index = count_path_nodes(_pathvector[i]) - 1;
118 } else if (!_pathvector[i].closed() || j != 0) {
119 previous_index = j - 1;
120 }
121 if (!_pathvector[i].closed() && j == 0) {
122 _nodesatellites[i][j].amount = 0;
123 continue;
124 }
125 if (count_path_nodes(_pathvector[i]) == j) {
126 continue;
127 }
128 if ((!apply_no_radius && _nodesatellites[i][j].amount == 0) ||
129 (!apply_with_radius && _nodesatellites[i][j].amount != 0)) {
130 continue;
131 }
132
133 if (_nodesatellites[i][j].selected || !only_selected) {
134 if (!use_knot_distance && !flexible) {
135 if (previous_index) {
136 _nodesatellites[i][j].amount =
137 _nodesatellites[i][j].radToLen(power, _pathvector[i][*previous_index], _pathvector[i][j]);
138 if (power && !_nodesatellites[i][j].amount) {
139 g_warning("Seems a too high radius value");
140 }
141 } else {
142 _nodesatellites[i][j].amount = 0.0;
143 }
144 } else {
145 _nodesatellites[i][j].amount = power;
146 }
147 }
148 }
149 }
150}
151
152void PathVectorNodeSatellites::convertUnit(Glib::ustring in, Glib::ustring to, bool apply_no_radius,
153 bool apply_with_radius)
154{
155 for (size_t i = 0; i < _nodesatellites.size(); ++i) {
156 for (size_t j = 0; j < _nodesatellites[i].size(); ++j) {
157 if (!_pathvector[i].closed() && j == 0) {
158 _nodesatellites[i][j].amount = 0;
159 continue;
160 }
161 if (count_path_nodes(_pathvector[i]) == j) {
162 continue;
163 }
164 if ((!apply_no_radius && _nodesatellites[i][j].amount == 0) ||
165 (!apply_with_radius && _nodesatellites[i][j].amount != 0)) {
166 continue;
167 }
168 _nodesatellites[i][j].amount =
169 Inkscape::Util::Quantity::convert(_nodesatellites[i][j].amount, in.c_str(), to.c_str());
170 }
171 }
172}
173
174void PathVectorNodeSatellites::updateNodeSatelliteType(NodeSatelliteType nodesatellitetype, bool apply_no_radius,
175 bool apply_with_radius, bool only_selected)
176{
177 for (size_t i = 0; i < _nodesatellites.size(); ++i) {
178 for (size_t j = 0; j < _nodesatellites[i].size(); ++j) {
179 if ((!apply_no_radius && _nodesatellites[i][j].amount == 0) ||
180 (!apply_with_radius && _nodesatellites[i][j].amount != 0)) {
181 continue;
182 }
183 if (count_path_nodes(_pathvector[i]) == j) {
184 if (!only_selected) {
185 _nodesatellites[i][j].nodesatellite_type = nodesatellitetype;
186 }
187 continue;
188 }
189 if (only_selected) {
190 if (_nodesatellites[i][j].selected) {
191 _nodesatellites[i][j].nodesatellite_type = nodesatellitetype;
192 }
193 } else {
194 _nodesatellites[i][j].nodesatellite_type = nodesatellitetype;
195 }
196 }
197 }
198}
199
201{
202 // pathv && _pathvector came here:
203 // * with different number of nodes
204 // * without empty subpats
205 // * _pathvector and nodesatellites (old data) are paired
206 NodeSatellites nodesatellites;
207
208 // TODO evaluate fix on nodes at same position
209 // size_t number_nodes = count_pathvector_nodes(pathv);
210 // size_t previous_number_nodes = getTotalNodeSatellites();
211 size_t npaths = pathv.size();
212 for (size_t i = 0; i < npaths; ++i) {
213 std::vector<NodeSatellite> path_nodesatellites;
214 size_t count = count_path_nodes(pathv[i]);
215 for (size_t j = 0; j < count; ++j) {
216 bool found = false;
217 for (size_t k = 0; k < _pathvector.size(); ++k) {
218 size_t countnodes = count_path_nodes(_pathvector[k]);
219 size_t countcurves = count_path_curves(_pathvector[k]);
220 if (!_nodesatellites.empty() && !_nodesatellites[k].empty()) {
221 assert(countnodes == _nodesatellites[k].size());
222 for (size_t l = 0; l < countcurves; ++l) {
223 if (Geom::are_near(_pathvector[k][l].initialPoint(), pathv[i][j].initialPoint(), 0.001)) { // epsilon is not enought big
224 path_nodesatellites.push_back(_nodesatellites[k][l]);
225 found = true;
226 break;
227 }
228 }
229 }
230 if (found) {
231 break;
232 }
233 }
234 if (!found) {
235 if (_pathvector.empty()) {
236 if (i < _nodesatellites.size() && j < _nodesatellites[i].size()) {
237 path_nodesatellites.push_back(_nodesatellites[i][j]);
238 } else {
239 path_nodesatellites.push_back(S);
240 }
241 } else {
242 path_nodesatellites.push_back(S);
243 }
244 }
245 }
246 nodesatellites.push_back(path_nodesatellites);
247 }
248 setPathVector(pathv);
249 setNodeSatellites(nodesatellites);
250}
251
252/*
253 Local Variables:
254 mode:c++
255 c-file-style:"stroustrup"
256 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
257 indent-tabs-mode:nil
258 fill-column:99
259 End:
260*/
261// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
bool is(S const *s)
Equivalent to the boolean value of dynamic_cast<T const*>(...).
Definition cast.h:37
Sequence of subpaths.
Definition pathvector.h:122
size_type size() const
Get the number of paths in the vector.
Definition pathvector.h:147
bool empty() const
Check whether the vector contains any paths.
Definition pathvector.h:145
static double convert(double from_dist, Unit const *from, Unit const *to)
Convert distances.
Definition units.cpp:588
NodeSatellite a per node holder of data.
void setPathVector(Geom::PathVector pathv)
void updateNodeSatelliteType(NodeSatelliteType nodesatellitetype, bool apply_no_radius, bool apply_with_radius, bool only_selected)
void convertUnit(Glib::ustring in, Glib::ustring to, bool apply_no_radius, bool apply_with_radius)
void recalculateForNewPathVector(Geom::PathVector const pathv, NodeSatellite const S)
std::pair< size_t, size_t > getIndexData(size_t index)
void setSelected(std::vector< size_t > selected)
void updateSteps(size_t steps, bool apply_no_radius, bool apply_with_radius, bool only_selected)
void setNodeSatellites(NodeSatellites nodesatellites)
void updateAmount(double radius, bool apply_no_radius, bool apply_with_radius, bool only_selected, bool use_knot_distance, bool flexible)
Geom::IntPoint size
NodeSatelliteType
PathVectorNodeSatellites a class to manage nodesatellites -per node extra data- in a pathvector.
std::vector< std::vector< NodeSatellite > > NodeSatellites
size_t count_path_nodes(Geom::Path const &path)
Definition geom.cpp:796
size_t count_path_curves(Geom::Path const &path)
Definition geom.cpp:821
Specific geometry functions for Inkscape, not provided my lib2geom.
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
static gint counter
Definition box3d.cpp:39
int index