ACF $AcfVersion:0$
TComposedColor.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR LicenseRef-ACF-Commercial
2#pragma once
3
4
5// STL includes
6#include <cstring>
7
8// ACF includes
10#include <iser/ISerializable.h>
11#include <iser/CArchiveTag.h>
12#include <imath/IDoubleManip.h>
13#include <imath/TVector.h>
14#include <imath/CVarVector.h>
15#include <icmm/icmm.h>
16
17
18namespace icmm
19{
20
21
140template <int Size>
141class TComposedColor: public imath::TVector<Size>, virtual public iser::ISerializable
142{
143public:
146
149 explicit TComposedColor(const imath::CVarVector& vector);
150 TComposedColor(const TComposedColor<Size>& color) = default;
151
157 void GetRounded(const imath::IDoubleManip& manipulator, TComposedColor<Size>& result);
158
164 bool IsRoundedEqual(const TComposedColor<Size>& color, const imath::IDoubleManip& manipulator) const;
165
169 bool IsSimilar(const TComposedColor<Size>& color, double tolerance = I_BIG_EPSILON) const;
170
175 bool IsNormalized() const;
176
181 void Normalize();
182
188
193
194 TComposedColor<Size> operator*(double value) const;
195 TComposedColor<Size> operator/(double value) const;
196
198 const TComposedColor<Size>& operator=(double colorValue);
199
204
205 const TComposedColor<Size>& operator*=(double value);
206 const TComposedColor<Size>& operator/=(double value);
207
208 // reimplemented (iser::ISerializable)
209 virtual bool Serialize(iser::IArchive& archive) override;
210};
211
212
213// inline methods
214
215template <int Size>
220
221
222template <int Size>
224: BaseClass(value)
225{
226}
227
228
229template <int Size>
231{
232 int commonSize = qMin(vector.GetElementsCount(), Size);
233 for (int copyIndex = 0; copyIndex < commonSize; ++copyIndex){
234 BaseClass::SetElement(copyIndex, vector[copyIndex]);
235 }
236
237 for (int resetIndex = commonSize; resetIndex < Size; ++resetIndex){
238 BaseClass::SetElement(resetIndex, 0.0);
239 }
240}
241
242
243template <int Size>
244inline bool TComposedColor<Size>::IsSimilar(const TComposedColor<Size>& color, double tolerance) const
245{
246 return GetDistance(color) <= tolerance;
247}
248
249
250template <int Size>
252{
253 for (int i = 0; i < Size; ++i){
254 double component = BaseClass::GetElement(i);
255
256 if ((component < 0) || (component > 1)){
257 return false;
258 }
259 }
260
261 return true;
262}
263
264
265template <int Size>
267{
269
270 for (int i = 0; i < Size; ++i){
271 retVal[i] = BaseClass::GetElement(i) + color[i];
272 }
273
274 return retVal;
275}
276
277
278template <int Size>
280{
282
283 for (int i = 0; i < Size; ++i){
284 retVal[i] = BaseClass::GetElement(i) - color[i];
285 }
286
287 return retVal;
288}
289
290
291template <int Size>
293{
295
296 for (int i = 0; i < Size; ++i){
297 retVal[i] = BaseClass::GetElement(i) * color[i];
298 }
299
300 return retVal;
301}
302
303
304template <int Size>
306{
308
309 for (int i = 0; i < Size; ++i){
310 retVal[i] = BaseClass::GetElement(i) / color[i];
311 }
312
313 return retVal;
314}
315
316
317template <int Size>
319{
321
322 for (int i = 0; i < Size; ++i){
323 retVal[i] = BaseClass::GetElement(i) * value;
324 }
325
326 return retVal;
327}
328
329
330template <int Size>
332{
334
335 for (int i = 0; i < Size; ++i){
336 retVal[i] = BaseClass::GetElement(i) / value;
337 }
338
339 return retVal;
340}
341
342
343template <int Size>
345{
346 for (int i = 0; i < Size; ++i){
347 BaseClass::SetElement(i, color[i]);
348 }
349
350 return *this;
351}
352
353
354template <int Size>
356{
357 std::memset(&BaseClass::GetElementsRef()[0], 0.0, sizeof(double) * Size);
358
359 BaseClass::SetElement(0, colorValue);
360
361 return *this;
362}
363
364
365template <int Size>
367{
368 BaseClass::operator+=(color);
369
370 return *this;
371}
372
373
374template <int Size>
376{
377 BaseClass::operator-=(color);
378
379 return *this;
380}
381
382
383template <int Size>
385{
386 Elements& elements = BaseClass::GetElementsRef();
387
388 for (int index = 0; index < Size; ++index){
389 elements[index] *= color[index];
390 }
391
392 return *this;
393}
394
395
396template <int Size>
398{
399 Elements& elements = BaseClass::GetElementsRef();
400
401 for (int index = 0; index < Size; ++index){
402 elements[index] /= color[index];
403 }
404
405 return *this;
406}
407
408
409template <int Size>
411{
412 BaseClass::operator*=(value);
413
414 return *this;
415}
416
417
418template <int Size>
420{
421 BaseClass::operator/=(value);
422
423 return *this;
424}
425
426
427// public normal methods
428
429template <int Size>
431{
432 for (int i = 0; i < Size; ++i){
433 result[i] = manipulator.GetRounded(BaseClass::GetElement(i));
434 }
435}
436
437
438template <int Size>
440{
441 for (int i = 0; i < Size; ++i){
442 if (!manipulator.AreValuesEqual(BaseClass::GetElement(i), color[i])){
443 return false;
444 }
445 }
446
447 return true;
448}
449
450
451template <int Size>
453{
454 Elements& elements = BaseClass::GetElementsRef();
455
456 for (int i = 0; i < Size; ++i){
457 if (elements[i] < 0.0){
458 elements[i] = 0.0;
459 }
460
461 if (elements[i] > 1.0){
462 elements[i] = 1.0;
463 }
464 }
465}
466
467
468template <int Size>
470{
471 result = *this;
472
473 result.Normalize();
474}
475
476
477// reimplemented (iser::ISerializable)
478
479template <int Size>
481{
482 static iser::CArchiveTag colorComponentsTag("ColorComponents", "List of color components", iser::CArchiveTag::TT_MULTIPLE);
483 static iser::CArchiveTag componentTag("Component", "Single component", iser::CArchiveTag::TT_LEAF, &colorComponentsTag);
484
485 istd::CChangeNotifier notifier(archive.IsStoring()? NULL: this, &GetAllChanges());
486 Q_UNUSED(notifier);
487
488 bool retVal = true;
489
490 int elementsCount = BaseClass::GetElementsCount();
491
492 retVal = retVal && archive.BeginMultiTag(colorComponentsTag, componentTag, elementsCount);
493
494 if ((!retVal) || (!archive.IsStoring() && (elementsCount != Size))){
495 return false;
496 }
497
498 for (int i = 0; i < elementsCount; ++i){
499 retVal = retVal && archive.BeginTag(componentTag);
500 retVal = retVal && archive.Process(BaseClass::GetElementRef(i));
501 retVal = retVal && archive.EndTag(componentTag);
502 }
503
504 retVal = retVal && archive.EndTag(colorComponentsTag);
505
506 return retVal;
507}
508
509
510// related global functions
511
512template <int Size>
513uint qHash(const TComposedColor<Size>& color, uint seed = 0)
514{
515 quint64 retVal = seed;
516
517 union{
518 double value;
519 quint64 raw;
520 } element;
521 element.raw = 0;
522
523 int elementsCount = color.GetElementsCount();
524 for (int i = 0; i < elementsCount; ++i){
525 element.value = color[i];
526
527 retVal = (retVal >> 1) ^ (element.raw + 1);
528 }
529
530 return uint(retVal);
531}
532
533
534} // namespace icmm
535
536
Generic fixed-size color implementation template.
TComposedColor< Size > operator*(const TComposedColor< Size > &color) const
const TComposedColor< Size > & operator=(const TComposedColor< Size > &color)
TComposedColor< Size > operator/(double value) const
const TComposedColor< Size > & operator=(double colorValue)
const TComposedColor< Size > & operator+=(const TComposedColor< Size > &color)
const TComposedColor< Size > & operator-=(const TComposedColor< Size > &color)
const TComposedColor< Size > & operator*=(const TComposedColor< Size > &color)
TComposedColor(const BaseClass &value)
const TComposedColor< Size > & operator*=(double value)
TComposedColor(const TComposedColor< Size > &color)=default
const TComposedColor< Size > & operator/=(double value)
bool IsRoundedEqual(const TComposedColor< Size > &color, const imath::IDoubleManip &manipulator) const
Check if two values are equal after rounding.
bool IsSimilar(const TComposedColor< Size > &color, double tolerance=I_BIG_EPSILON) const
Allows to compare two colors with tolerance.
void GetRounded(const imath::IDoubleManip &manipulator, TComposedColor< Size > &result)
Get color after components value rounding with specified precision.
TComposedColor< Size > operator*(double value) const
virtual bool Serialize(iser::IArchive &archive) override
Load or store state of this object as a archive stream.
BaseClass::Elements Elements
const TComposedColor< Size > & operator/=(const TComposedColor< Size > &color)
imath::TVector< Size > BaseClass
TComposedColor(const imath::CVarVector &vector)
void GetNormalized(TComposedColor< Size > &result) const
Get normalized color.
void Normalize()
Make this color to be normalized.
TComposedColor< Size > operator+(const TComposedColor< Size > &color) const
bool IsNormalized() const
Check if this color value is normalized.
TComposedColor< Size > operator-(const TComposedColor< Size > &color) const
TComposedColor< Size > operator/(const TComposedColor< Size > &color) const
Implementation of variable-size mathematical vector with double precision elements.
Definition CVarVector.h:110
int GetElementsCount() const
Get number of elements.
Definition CVarVector.h:387
Interface for all manipulation using values represent as double.
virtual bool AreValuesEqual(const ValueType &value1, const ValueType &value2) const =0
Compare two values and check, if there are equal.
virtual ValueType GetRounded(const ValueType &value) const =0
Get the nearest value rounded used this arithmetik.
Implementation of fixed-size mathematical vector with specified type of elements.
Definition TVector.h:95
static int GetElementsCount()
Get number of elements.
Definition TVector.h:904
Element Elements[Size]
Definition TVector.h:98
TVector< Size, Element > operator-() const
Definition TVector.h:817
Process tag used to group data in archive stream.
Definition CArchiveTag.h:22
@ TT_LEAF
Leaf tag, it can contain only one primitive element.
Definition CArchiveTag.h:48
@ TT_MULTIPLE
Multiple tag containing variable number of child tags.
Definition CArchiveTag.h:42
Represents an input/output persistence archive for object serialization.
Definition IArchive.h:164
virtual bool Process(bool &value)=0
Processes (reads or writes) a boolean value.
virtual bool EndTag(const CArchiveTag &tag)=0
Ends a tagged section in the archive.
virtual bool BeginMultiTag(const CArchiveTag &tag, const CArchiveTag &subTag, int &count)=0
Begins a tagged section containing multiple elements of the same type.
virtual bool IsStoring() const =0
Checks if this archive is in storing (writing) or loading (reading) mode.
virtual bool BeginTag(const CArchiveTag &tag)=0
Begins a tagged section in the archive.
Common class for all classes which objects can be archived or restored from archive.
Help class which provides the automatic update mechanism of the model.
#define NULL
Definition istd.h:74
static const double I_BIG_EPSILON
Definition istd.h:26
Contains color management classes.
uint qHash(const CFastColor &color, uint seed=0)