1
2
3 // TnzCore includes
4 #include "tgeometry.h"
5 #include "tstream.h"
6 #include "texception.h"
7
8 #include "toonz/vectorizerparameters.h"
9
10 //**************************************************************************
11 // Local namespace strings
12 //**************************************************************************
13
14 namespace {
15
16 const char *s_version = "version",
17
18 *s_generalConfiguration = "generalConfiguration",
19 *s_outline = "outline", *s_threshold = "threshold",
20 *s_leaveUnpainted = "leaveUnpainted",
21 *s_visibilityBits = "visibilityBits",
22
23 *s_Centerline = "Centerline", *s_despeckling = "despeckling",
24 *s_maxThickness = "maxThickness", *s_penalty = "penalty",
25 *s_thicknessRatio = "thicknessRatio", *s_makeFrame = "makeFrame",
26 *s_naaSource = "naaSource",
27
28 *s_accuracy = "accuracy",
29 *s_thicknessRatioFirst = "thicknessRatioFirst",
30 *s_thicknessRatioLast = "thicknessRatioLast",
31 *s_paintFill = "paintFill",
32 *s_alignBoundaryStrokesDirection = "alignBoundaryStrokesDirection",
33
34 *s_Outline = "Outline", *s_adherenceTol = "adherenceTol",
35 *s_angleTol = "angleTol", *s_relativeTol = "relativeTol",
36 *s_mergeTol = "mergeTol", *s_maxColors = "maxColors",
37 *s_transparentColor = "transparentColor", *s_toneTol = "toneTol",
38
39 *s_adherence = "adherence", *s_angle = "angle",
40 *s_relative = "relative", *s_toneThreshold = "toneThreshold";
41
42 } // namespace
43
44 //**************************************************************************
45 // Local namespace stuff
46 //**************************************************************************
47
48 namespace {
49
50 const VersionNumber l_versionNumber(71, 0);
51
52 //=======================================================
53
saveData(const VectorizerConfiguration & conf,TOStream & os)54 void saveData(const VectorizerConfiguration &conf, TOStream &os) {
55 int leaveUnpainted = conf.m_leaveUnpainted ? 1 : 0;
56
57 os.child(s_threshold) << conf.m_threshold;
58 os.child(s_leaveUnpainted) << leaveUnpainted;
59 }
60
61 //-------------------------------------------------------
62
loadData(VectorizerConfiguration & conf,TIStream & is)63 void loadData(VectorizerConfiguration &conf, TIStream &is) {
64 std::string tagName;
65 while (is.matchTag(tagName)) {
66 if (tagName == s_threshold)
67 is >> conf.m_threshold, is.matchEndTag();
68 else if (tagName == s_leaveUnpainted) {
69 int leaveUnpainted;
70 is >> leaveUnpainted,
71 conf.m_leaveUnpainted = (leaveUnpainted == 0) ? false : true;
72
73 is.matchEndTag();
74 } else
75 is.skipCurrentTag();
76 }
77 }
78
79 //-------------------------------------------------------
80
saveData(const CenterlineConfiguration & conf,TOStream & os)81 void saveData(const CenterlineConfiguration &conf, TOStream &os) {
82 os.openChild(s_generalConfiguration);
83 saveData(static_cast<const VectorizerConfiguration &>(conf), os);
84 os.closeChild();
85
86 int makeFrame = conf.m_makeFrame ? 1 : 0;
87
88 os.child(s_despeckling) << conf.m_despeckling;
89 os.child(s_maxThickness) << conf.m_maxThickness;
90 os.child(s_penalty) << conf.m_penalty;
91 os.child(s_thicknessRatio) << conf.m_thicknessRatio;
92 os.child(s_makeFrame) << makeFrame;
93 os.child(s_naaSource) << (conf.m_naaSource ? 1 : 0);
94 }
95
96 //-------------------------------------------------------
97
loadData(CenterlineConfiguration & conf,TIStream & is)98 void loadData(CenterlineConfiguration &conf, TIStream &is) {
99 std::string tagName;
100 while (is.matchTag(tagName)) {
101 if (tagName == s_generalConfiguration)
102 loadData(static_cast<VectorizerConfiguration &>(conf), is),
103 is.matchEndTag();
104 else if (tagName == s_despeckling)
105 is >> conf.m_despeckling, is.matchEndTag();
106 else if (tagName == s_maxThickness)
107 is >> conf.m_maxThickness, is.matchEndTag();
108 else if (tagName == s_penalty)
109 is >> conf.m_penalty, is.matchEndTag();
110 else if (tagName == s_thicknessRatio)
111 is >> conf.m_thicknessRatio, is.matchEndTag();
112 else if (tagName == s_makeFrame) {
113 int makeFrame;
114 is >> makeFrame, conf.m_makeFrame = (makeFrame == 0) ? false : true;
115 is.matchEndTag();
116 } else if (tagName == s_naaSource) {
117 int naaSource;
118 is >> naaSource, conf.m_naaSource = (naaSource == 0) ? false : true;
119 is.matchEndTag();
120 } else
121 is.skipCurrentTag();
122 }
123 }
124
125 //-------------------------------------------------------
126
saveData(const NewOutlineConfiguration & conf,TOStream & os)127 void saveData(const NewOutlineConfiguration &conf, TOStream &os) {
128 os.openChild(s_generalConfiguration);
129 saveData(static_cast<const VectorizerConfiguration &>(conf), os);
130 os.closeChild();
131
132 os.child(s_despeckling) << conf.m_despeckling;
133 os.child(s_adherenceTol) << conf.m_adherenceTol;
134 os.child(s_angleTol) << conf.m_angleTol;
135 os.child(s_relativeTol) << conf.m_relativeTol;
136 os.child(s_mergeTol) << conf.m_mergeTol;
137 os.child(s_maxColors) << conf.m_maxColors;
138 os.child(s_transparentColor) << conf.m_transparentColor;
139 os.child(s_toneTol) << conf.m_toneTol;
140 }
141
142 //-------------------------------------------------------
143
loadData(NewOutlineConfiguration & conf,TIStream & is)144 void loadData(NewOutlineConfiguration &conf, TIStream &is) {
145 std::string tagName;
146 while (is.matchTag(tagName)) {
147 if (tagName == s_generalConfiguration)
148 loadData(static_cast<VectorizerConfiguration &>(conf), is),
149 is.matchEndTag();
150 else if (tagName == s_despeckling)
151 is >> conf.m_despeckling, is.matchEndTag();
152 else if (tagName == s_adherenceTol)
153 is >> conf.m_adherenceTol, is.matchEndTag();
154 else if (tagName == s_angleTol)
155 is >> conf.m_angleTol, is.matchEndTag();
156 else if (tagName == s_relativeTol)
157 is >> conf.m_relativeTol, is.matchEndTag();
158 else if (tagName == s_mergeTol)
159 is >> conf.m_mergeTol, is.matchEndTag();
160 else if (tagName == s_maxColors)
161 is >> conf.m_maxColors, is.matchEndTag();
162 else if (tagName == s_transparentColor)
163 is >> conf.m_transparentColor, is.matchEndTag();
164 else if (tagName == s_toneTol)
165 is >> conf.m_toneTol, is.matchEndTag();
166 else
167 is.skipCurrentTag();
168 }
169 }
170
171 //-------------------------------------------------------
172
convert(const CenterlineConfiguration & conf,VectorizerParameters & params)173 void convert(const CenterlineConfiguration &conf,
174 VectorizerParameters ¶ms) {
175 params.m_cThreshold = conf.m_threshold / 25.0;
176 params.m_cAccuracy = 10 - conf.m_penalty;
177 params.m_cDespeckling = conf.m_despeckling / 2.0;
178 params.m_cMaxThickness = conf.m_maxThickness * 2;
179 // params.m_cThicknessRatio = centConf.m_thicknessRatio;
180 params.m_cThicknessRatioFirst = conf.m_thicknessRatio;
181 params.m_cThicknessRatioLast = conf.m_thicknessRatio;
182 params.m_cMakeFrame = conf.m_makeFrame;
183 params.m_cPaintFill = !conf.m_leaveUnpainted;
184 params.m_cAlignBoundaryStrokesDirection =
185 conf.m_alignBoundaryStrokesDirection;
186 params.m_cNaaSource = conf.m_naaSource;
187 }
188
189 //-------------------------------------------------------
190
convert(const NewOutlineConfiguration & conf,VectorizerParameters & params)191 void convert(const NewOutlineConfiguration &conf,
192 VectorizerParameters ¶ms) {
193 params.m_oDespeckling = conf.m_despeckling;
194 params.m_oAccuracy = tround((5.0 - conf.m_mergeTol) * 2.0);
195 params.m_oAdherence = tround(conf.m_adherenceTol * 100.0);
196 params.m_oAngle = tround(conf.m_angleTol * 180.0);
197 params.m_oRelative = tround(conf.m_relativeTol * 100.0);
198 params.m_oMaxColors = conf.m_maxColors;
199 params.m_oToneThreshold = conf.m_toneTol;
200 params.m_oTransparentColor = conf.m_transparentColor;
201 params.m_oPaintFill = !conf.m_leaveUnpainted;
202 params.m_oAlignBoundaryStrokesDirection =
203 conf.m_alignBoundaryStrokesDirection;
204 }
205
206 } // namespace
207
208 //**************************************************************************
209 // VectorizerConfiguration implementation
210 //**************************************************************************
211
212 PERSIST_IDENTIFIER(VectorizerParameters, "vectorizerParameters")
213
214 //--------------------------------------------------------------------------
215
VectorizerParameters()216 VectorizerParameters::VectorizerParameters()
217 : m_visibilityBits(-1) // All visible by default
218 , m_isOutline(false) {
219 CenterlineConfiguration cConf;
220 convert(cConf, *this);
221
222 NewOutlineConfiguration oConf;
223 convert(oConf, *this);
224 }
225
226 //--------------------------------------------------------------------------
227
getCenterlineConfiguration(double frame) const228 CenterlineConfiguration VectorizerParameters::getCenterlineConfiguration(
229 double frame) const {
230 CenterlineConfiguration conf;
231
232 conf.m_outline = false;
233 conf.m_threshold = m_cThreshold * 25;
234 conf.m_penalty = 10 - m_cAccuracy; // m_cAccuracy in [1,10]
235 conf.m_despeckling = m_cDespeckling * 2;
236 conf.m_maxThickness = m_cMaxThickness / 2.0;
237 // conf.m_thicknessRatio = m_cThicknessRatio;
238 conf.m_thicknessRatio =
239 (1 - frame) * m_cThicknessRatioFirst + frame * m_cThicknessRatioLast;
240 conf.m_leaveUnpainted = !m_cPaintFill;
241 conf.m_alignBoundaryStrokesDirection = m_cAlignBoundaryStrokesDirection;
242 conf.m_makeFrame = m_cMakeFrame;
243 conf.m_naaSource = m_cNaaSource;
244
245 return conf;
246 }
247
248 //--------------------------------------------------------------------------
249
getOutlineConfiguration(double frame) const250 NewOutlineConfiguration VectorizerParameters::getOutlineConfiguration(
251 double frame) const {
252 NewOutlineConfiguration conf;
253
254 conf.m_outline = true;
255 conf.m_despeckling = m_oDespeckling;
256 conf.m_adherenceTol = m_oAdherence * 0.01;
257 conf.m_angleTol = m_oAngle / 180.0;
258 conf.m_relativeTol = m_oRelative * 0.01;
259 conf.m_mergeTol = 5.0 - m_oAccuracy * 0.5;
260 conf.m_leaveUnpainted = !m_oPaintFill;
261 conf.m_alignBoundaryStrokesDirection = m_oAlignBoundaryStrokesDirection;
262 conf.m_maxColors = m_oMaxColors;
263 conf.m_transparentColor = m_oTransparentColor;
264 conf.m_toneTol = m_oToneThreshold;
265
266 return conf;
267 }
268
269 //--------------------------------------------------------------------------
270
saveData(TOStream & os)271 void VectorizerParameters::saveData(TOStream &os) {
272 os.child(s_version) << l_versionNumber.first << l_versionNumber.second;
273 os.child(s_outline) << (m_isOutline ? 1 : 0);
274 os.child(s_visibilityBits) << int(m_visibilityBits);
275
276 os.openChild(s_Centerline);
277 {
278 os.child(s_threshold) << m_cThreshold;
279 os.child(s_accuracy) << m_cAccuracy;
280 os.child(s_despeckling) << m_cDespeckling;
281 os.child(s_maxThickness) << m_cMaxThickness;
282 os.child(s_thicknessRatioFirst) << m_cThicknessRatioFirst;
283 os.child(s_thicknessRatioLast) << m_cThicknessRatioLast;
284 os.child(s_makeFrame) << (m_cMakeFrame ? 1 : 0);
285 os.child(s_paintFill) << (m_cPaintFill ? 1 : 0);
286 os.child(s_alignBoundaryStrokesDirection)
287 << (m_cAlignBoundaryStrokesDirection ? 1 : 0);
288 os.child(s_naaSource) << (m_cNaaSource ? 1 : 0);
289 }
290 os.closeChild();
291
292 os.openChild(s_Outline);
293 {
294 os.child(s_despeckling) << m_oDespeckling;
295 os.child(s_accuracy) << m_oAccuracy;
296 os.child(s_adherence) << m_oAdherence;
297 os.child(s_angle) << m_oAngle;
298 os.child(s_relative) << m_oRelative;
299 os.child(s_maxColors) << m_oMaxColors;
300 os.child(s_toneThreshold) << m_oToneThreshold;
301 os.child(s_transparentColor) << m_oTransparentColor;
302 os.child(s_paintFill) << (m_oPaintFill ? 1 : 0);
303 os.child(s_alignBoundaryStrokesDirection)
304 << (m_oAlignBoundaryStrokesDirection ? 1 : 0);
305 }
306 os.closeChild();
307 }
308
309 //--------------------------------------------------------------------------
310
loadData(TIStream & is)311 void VectorizerParameters::loadData(TIStream &is) {
312 VersionNumber version;
313
314 std::string tagName;
315 int val;
316
317 while (is.matchTag(tagName)) {
318 if (tagName == s_version)
319 is >> version.first >> version.second, is.matchEndTag();
320 else if (tagName == s_outline)
321 is >> val, m_isOutline = (val != 0), is.matchEndTag();
322 else if (tagName == s_visibilityBits) {
323 is >> val, is.matchEndTag();
324
325 if (version ==
326 l_versionNumber) // Restore visibility bits only if the parameters
327 m_visibilityBits =
328 val; // version is current - defaulting them is no big deal.
329 } else if (tagName == s_Centerline) {
330 while (is.matchTag(tagName)) {
331 if (tagName == s_threshold)
332 is >> m_cThreshold, is.matchEndTag();
333 else if (tagName == s_accuracy)
334 is >> m_cAccuracy, is.matchEndTag();
335 else if (tagName == s_despeckling)
336 is >> m_cDespeckling, is.matchEndTag();
337 else if (tagName == s_maxThickness)
338 is >> m_cMaxThickness, is.matchEndTag();
339 else if (tagName == s_thicknessRatioFirst)
340 is >> m_cThicknessRatioFirst, is.matchEndTag();
341 else if (tagName == s_thicknessRatioLast)
342 is >> m_cThicknessRatioLast, is.matchEndTag();
343 else if (tagName == s_makeFrame)
344 is >> val, m_cMakeFrame = (val != 0), is.matchEndTag();
345 else if (tagName == s_paintFill)
346 is >> val, m_cPaintFill = (val != 0), is.matchEndTag();
347 else if (tagName == s_alignBoundaryStrokesDirection)
348 is >> val, m_cAlignBoundaryStrokesDirection = (val != 0),
349 is.matchEndTag();
350 else if (tagName == s_naaSource)
351 is >> val, m_cNaaSource = (val != 0), is.matchEndTag();
352 else
353 is.skipCurrentTag();
354 }
355
356 is.matchEndTag();
357 } else if (tagName == s_Outline) {
358 while (is.matchTag(tagName)) {
359 if (tagName == s_despeckling)
360 is >> m_oDespeckling, is.matchEndTag();
361 else if (tagName == s_accuracy)
362 is >> m_oAccuracy, is.matchEndTag();
363 else if (tagName == s_adherence)
364 is >> m_oAdherence, is.matchEndTag();
365 else if (tagName == s_angle)
366 is >> m_oAngle, is.matchEndTag();
367 else if (tagName == s_relative)
368 is >> m_oRelative, is.matchEndTag();
369 else if (tagName == s_maxColors)
370 is >> m_oMaxColors, is.matchEndTag();
371 else if (tagName == s_toneThreshold)
372 is >> m_oToneThreshold, is.matchEndTag();
373 else if (tagName == s_transparentColor)
374 is >> m_oTransparentColor, is.matchEndTag();
375 else if (tagName == s_paintFill)
376 is >> val, m_oPaintFill = (val != 0), is.matchEndTag();
377 else if (tagName == s_alignBoundaryStrokesDirection)
378 is >> val, m_oAlignBoundaryStrokesDirection = (val != 0),
379 is.matchEndTag();
380 else
381 is.skipCurrentTag();
382 }
383
384 is.matchEndTag();
385 } else if (tagName ==
386 "CenterlineConfiguration") // Old tags, not saved anymore
387 {
388 CenterlineConfiguration conf;
389 ::loadData(conf, is), is.matchEndTag();
390
391 convert(conf, *this);
392 } else if (tagName == "NewOutlineConfiguration") //
393 {
394 NewOutlineConfiguration conf;
395 ::loadData(conf, is), is.matchEndTag();
396
397 convert(conf, *this);
398 } else
399 is.skipCurrentTag();
400 }
401 }
402