Visual Computing Library  devel
Loading...
Searching...
No Matches
color.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_ALGORITHMS_MESH_UPDATE_COLOR_H
24#define VCL_ALGORITHMS_MESH_UPDATE_COLOR_H
25
26#include <vclib/algorithms/mesh/stat.h>
27
28#include <vclib/mesh.h>
29#include <vclib/space/core.h>
30
31#include <set>
32
33namespace vcl {
34
35namespace detail {
36
37struct ColorAvgInfo
38{
39 Point4<uint> c;
40 uint cnt = 0;
41};
42
43template<uint ELEM_ID, MeshConcept MeshType>
44void setPerElemColorFromVertexColor(MeshType& m)
45{
46 requirePerVertexColor(m);
47 requirePerElementComponent<ELEM_ID, CompId::VERTEX_REFERENCES>(m);
48 requirePerElementComponent<ELEM_ID, CompId::COLOR>(m);
49
50 for (auto& e : m.template elements<ELEM_ID>()) {
51 Point4<uint> avg(0, 0, 0, 0);
52 for (const auto* v : e.vertices()) {
53 avg += v->color().template cast<uint>();
54 }
55 avg /= e.vertexNumber();
56 e.color() = avg.template cast<uint8_t>();
57 }
58}
59
60template<uint ELEM_ID, MeshConcept MeshType>
61void setPerVertexColorFromElemColor(MeshType& m)
62{
63 requirePerVertexColor(m);
64 requirePerElementComponent<ELEM_ID, CompId::VERTEX_REFERENCES>(m);
65 requirePerElementComponent<ELEM_ID, CompId::COLOR>(m);
66
67 std::vector<ColorAvgInfo> avgColors(m.vertexContainerSize());
68
69 for (const auto& e : m.template elements<ELEM_ID>()) {
70 for (const auto* v : e.vertices()) {
71 avgColors[v->index()].c += e.color().template cast<uint>();
72 avgColors[v->index()].cnt[v->index()]++;
73 }
74 }
75
76 for (auto& v : m.vertices()) {
77 if (avgColors[v.index()].cnt > 0) {
78 avgColors[v.index()] /= avgColors[v.index()].cnt[v.index()];
79 v.color() = avgColors[v.index()].c.template cast<uint8_t>();
80 }
81 }
82}
83
84} // namespace detail
85
103template<MeshConcept MeshType>
105 MeshType& m,
106 Color c = Color::White,
107 bool onlySelected = false)
108{
109 requirePerVertexColor(m);
110
111 if (onlySelected) {
112 std::ranges::fill(m.vertices() | views::selected | views::colors, c);
113 }
114 else {
115 std::ranges::fill(m.vertices() | views::colors, c);
116 }
117}
118
137template<FaceMeshConcept MeshType>
139 MeshType& m,
140 Color c = Color::White,
141 bool onlySelected = false)
142{
144
145 if (onlySelected) {
146 std::ranges::fill(m.faces() | views::selected | views::colors, c);
147 }
148 else {
149 std::ranges::fill(m.faces() | views::colors, c);
150 }
151}
152
171template<EdgeMeshConcept MeshType>
173 MeshType& m,
174 Color c = Color::White,
175 bool onlySelected = false)
176{
178
179 if (onlySelected) {
180 std::ranges::fill(m.edges() | views::selected | views::colors, c);
181 }
182 else {
183 std::ranges::fill(m.edges() | views::colors, c);
184 }
185}
186
198template<HasColor MeshType>
199void setMeshColor(MeshType& m, Color c = Color::White)
200{
201 m.color() = c;
202}
203
220template<FaceMeshConcept MeshType>
222{
223 detail::setPerVertexColorFromElemColor<ElemId::FACE>(m);
224}
225
242template<FaceMeshConcept MeshType>
244{
245 detail::setPerElemColorFromVertexColor<ElemId::FACE>(m);
246}
247
264template<EdgeMeshConcept MeshType>
266{
267 detail::setPerElemColorFromVertexColor<ElemId::EDGE>(m);
268}
269
294template<MeshConcept MeshType>
296 MeshType& m,
297 Color::ColorMap colorMap = Color::ColorMap::RedBlue,
298 typename MeshType::VertexType::QualityType minQuality = 0,
299 typename MeshType::VertexType::QualityType maxQuality = 0)
300{
301 requirePerVertexColor(m);
302 requirePerVertexQuality(m);
303
304 using VertexType = MeshType::VertexType;
305 using QualityType = VertexType::QualityType;
306
307 if (minQuality == maxQuality) {
308 std::pair<QualityType, QualityType> pair = vertexQualityMinMax(m);
309 minQuality = pair.first;
310 maxQuality = pair.second;
311 }
312 for (VertexType& v : m.vertices()) {
313 v.color() =
314 colorFromInterval(minQuality, maxQuality, v.quality(), colorMap);
315 }
316}
317
342template<FaceMeshConcept MeshType>
344 MeshType& m,
345 Color::ColorMap colorMap = Color::ColorMap::RedBlue,
346 typename MeshType::FaceType::QualityType minQuality = 0,
347 typename MeshType::FaceType::QualityType maxQuality = 0)
348{
351
352 using FaceType = MeshType::FaceType;
353 using QualityType = FaceType::QualityType;
354
355 if (minQuality == maxQuality) {
356 std::pair<QualityType, QualityType> pair = faceQualityMinMax(m);
357
358 minQuality = pair.first;
359 maxQuality = pair.second;
360 }
361 for (FaceType& f : m.faces()) {
362 f.color() =
363 colorFromInterval(minQuality, maxQuality, f.quality(), colorMap);
364 }
365}
366
392template<FaceMeshConcept MeshType>
394 MeshType& m,
395 Color borderColor = Color::Blue,
396 Color internalColor = Color::White,
397 Color mixColor = Color::Cyan)
398{
399 requirePerVertexColor(m);
400
401 using FaceType = MeshType::FaceType;
402
403 const Color baseColor = Color::Green;
404
406
407 for (FaceType& f : m.faces()) {
408 for (uint i = 0; i < f.vertexNumber(); ++i) {
409 if (f.edgeOnBorder(i)) {
410 if (f.vertex(i).color() == baseColor)
411 f.vertex(i).color() = borderColor;
412 if (f.vertex(i).color() == internalColor)
413 f.vertex(i).color() = mixColor;
414 if (f.vertexMod(i + 1).color() == baseColor)
415 f.vertexMod(i + 1).color() = borderColor;
416 if (f.vertexMod(i + 1).color() == internalColor)
417 f.vertexMod(i + 1).color() = mixColor;
418 }
419 else {
420 if (f.vertex(i).color() == baseColor)
421 f.vertex(i).color() = internalColor;
422 if (f.vertex(i).color() == borderColor)
423 f.vertex(i).color() = mixColor;
424 if (f.vertexMod(i + 1).color() == baseColor)
425 f.vertexMod(i + 1).color() = internalColor;
426 if (f.vertexMod(i + 1).color() == borderColor)
427 f.vertexMod(i + 1).color() = mixColor;
428 }
429 }
430 }
431}
432
451template<FaceMeshConcept MeshType>
453 MeshType& m,
454 const std::vector<std::set<uint>>& connectedComponents)
455{
456 std::vector<Color> vc = colorScattering(connectedComponents.size());
457
458 uint cid = 0;
459 for (const std::set<uint>& connComp : connectedComponents) {
460 for (const uint& fid : connComp) {
461 m.face(fid).color() = vc[cid];
462 }
463 cid++;
464 }
465}
466
484template<FaceMeshConcept MeshType>
493
518template<FaceMeshConcept MeshType>
520 MeshType& m,
521 uint nColors = 50,
522 bool checkFauxEdges = true)
523{
525
526 using FaceType = MeshType::FaceType;
527
528 Color baseColor = Color::Black;
530
531 std::vector<Color> vc = colorScattering(nColors);
532
533 for (FaceType& f : m.faces()) {
534 if (f.color() == baseColor) {
535 f.color() = vc[m.index(f) % nColors];
536 }
537 if constexpr (HasPerFaceAdjacentFaces<MeshType>) {
539 for (uint i = 0; i < f.vertexNumber(); ++i) {
540 if (f.edgeFaux(i)) {
541 assert(f.adjFace(i) != nullptr);
542 f.adjFace(i)->color = f.color();
543 }
544 }
545 }
546 }
547 }
548}
549
571template<MeshConcept MeshType, PointConcept PointType>
573 MeshType& m,
574 PointType period,
575 PointType offset = PointType(0, 0, 0),
576 bool onSelected = false)
577{
578 requirePerVertexColor(m);
579
580 using VertexType = MeshType::VertexType;
581
582 PointType p[3];
583
584 for (VertexType& v : m.vertices()) {
585 if (!onSelected || v.selected()) {
586 p[0] = (v.position() / period[0]) + offset;
587 p[1] = (v.position() / period[1]) + offset;
588 p[2] = (v.position() / period[2]) + offset;
589 v.color() = Color(
590 127 + 128.0 * perlinNoise(p[0][0], p[0][1], p[0][2]),
591 127 + 128.0 * perlinNoise(p[1][0], p[1][1], p[1][2]),
592 127 + 128.0 * perlinNoise(p[2][0], p[2][1], p[2][2]),
593 255);
594 }
595 }
596}
597
616template<MeshConcept MeshType, PointConcept PointType>
618 MeshType& m,
619 double period,
620 PointType offset = PointType(0, 0, 0),
621 Color color1 = Color::Black,
622 Color color2 = Color::White,
623 bool onSelected = false)
624{
625 requirePerVertexColor(m);
626
627 using VertexType = MeshType::VertexType;
628
629 for (VertexType& v : m.vertices()) {
630 if (!onSelected || v.selected()) {
631 PointType p = v.position() / period + offset;
632
633 double factor = (perlinNoise(p[0], p[1], p[2]) + 1.0) / 2.0;
634
635 int rr = (color1[0] * factor) + (color2[0] * (1.0 - factor));
636 int gg = (color1[1] * factor) + (color2[1] * (1.0 - factor));
637 int bb = (color1[2] * factor) + (color2[2] * (1.0 - factor));
638 int aa = (color1[3] * factor) + (color2[3] * (1.0 - factor));
639
640 v.color() = Color(rr, gg, bb, aa);
641 }
642 }
643}
644
645} // namespace vcl
646
647#endif // VCL_ALGORITHMS_MESH_UPDATE_COLOR_H
A class representing a box in N-dimensional space.
Definition box.h:46
The Color class represents a 32 bit color.
Definition color.h:48
ColorMap
List of Color Maps supported by the vcl::Color.
Definition color.h:126
Concept that checks if a Mesh has the per Face AdjacentFaces component.
Definition face_requirements.h:109
std::vector< std::set< uint > > connectedComponents(const MeshType &m)
Computes the connected components of the input mesh based on its topology.
Definition topology.h:598
void requirePerEdgeColor(const MeshType &m)
This function asserts that a Mesh has a EdgeContainer, the Edge has a Color Component,...
Definition edge_requirements.h:704
bool isPerFaceAdjacentFacesAvailable(const MeshType &m)
Returns true if the AdjacentFaces component is available (enabled) in the Face element of the input m...
Definition face_requirements.h:415
void requirePerFaceQuality(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a Quality Component,...
Definition face_requirements.h:1137
void requirePerFaceColor(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a Color Component,...
Definition face_requirements.h:996
void setPerVertexColorFromFaceColor(MeshType &m)
Sets the vertex colors from its incident face colors, computing a plain average of the face colors.
Definition color.h:221
void setPerFaceColorScattering(MeshType &m, uint nColors=50, bool checkFauxEdges=true)
This function colors each face of the mesh using a given number of scattering colors (default number ...
Definition color.h:519
void setPerVertexColorPerlinNoise(MeshType &m, PointType period, PointType offset=PointType(0, 0, 0), bool onSelected=false)
Set the vertex color according to a perlin noise computed on the vertex positions.
Definition color.h:572
void setPerVertexPerlinColor(MeshType &m, double period, PointType offset=PointType(0, 0, 0), Color color1=Color::Black, Color color2=Color::White, bool onSelected=false)
Simple Perlin color mixing. color1 and color2 are mixed according the perlin noise function,...
Definition color.h:617
void setPerFaceColor(MeshType &m, Color c=Color::White, bool onlySelected=false)
Sets the color of the faces. If the onlySelected flag is set to true, only the color of the selected ...
Definition color.h:138
void setPerVertexColorFromQuality(MeshType &m, Color::ColorMap colorMap=Color::ColorMap::RedBlue, typename MeshType::VertexType::QualityType minQuality=0, typename MeshType::VertexType::QualityType maxQuality=0)
Sets the vertex colors from the quality values by computing a shading in the given color map (default...
Definition color.h:295
void setPerFaceColorFromQuality(MeshType &m, Color::ColorMap colorMap=Color::ColorMap::RedBlue, typename MeshType::FaceType::QualityType minQuality=0, typename MeshType::FaceType::QualityType maxQuality=0)
Sets the face colors from the quality values by computing a shading in the given color map (default i...
Definition color.h:343
void setPerFaceColorFromVertexColor(MeshType &m)
Sets the face colors from its incident vertex colors, computing a plain average of the vertex colors.
Definition color.h:243
void setPerEdgeColorFromVertexColor(MeshType &m)
Sets the edge colors from its incident vertex colors, computing a plain average of the vertex colors.
Definition color.h:265
void setPerVertexColor(MeshType &m, Color c=Color::White, bool onlySelected=false)
Sets the color of the vertices. If the onlySelected flag is set to true, only the color of the select...
Definition color.h:104
void setMeshColor(MeshType &m, Color c=Color::White)
Sets the color component of a mesh.
Definition color.h:199
void setPerVertexColorFromFaceBorderFlag(MeshType &m, Color borderColor=Color::Blue, Color internalColor=Color::White, Color mixColor=Color::Cyan)
Color the vertices of the mesh that are on border, using the border flags of the faces.
Definition color.h:393
void setPerFaceColorFromConnectedComponents(MeshType &m, const std::vector< std::set< uint > > &connectedComponents)
Given an already computed vector of sets of connected components (see vcl::connectedComponents(m) in ...
Definition color.h:452
void setPerEdgeColor(MeshType &m, Color c=Color::White, bool onlySelected=false)
Sets the color of the edges. If the onlySelected flag is set to true, only the color of the selected ...
Definition color.h:172
constexpr detail::VerticesView vertices
A view that allows to iterate over the Vertex elements of an object.
Definition vertex.h:92