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++;
73 }
74 }
75
76 for (auto& v : m.vertices()) {
77 if (avgColors[v.index()].cnt > 0) {
78 avgColors[v.index()].c /= avgColors[v.index()].cnt;
79 v.color() = avgColors[v.index()].c.template cast<uint8_t>();
80 }
81 }
82}
83
84template<uint ELEM_ID, MeshConcept MeshType>
85void setPerElemColorFromMaterial(MeshType& m)
86{
87 static_assert(
88 HasMaterials<MeshType>,
89 "The input Mesh must have the Materials component.");
90 requirePerElementComponent<ELEM_ID, CompId::COLOR>(m);
91 requirePerElementComponent<ELEM_ID, CompId::MATERIAL_INDEX>(m);
92
93 for (auto& e : m.template elements<ELEM_ID>()) {
94 uint matIndex = e.materialIndex();
95 if (matIndex < m.materialsNumber()) {
96 e.color() = m.materials()[matIndex].baseColor();
97 }
98 }
99}
100
101} // namespace detail
102
120template<MeshConcept MeshType>
122 MeshType& m,
123 Color c = Color::White,
124 bool onlySelected = false)
125{
126 requirePerVertexColor(m);
127
128 if (onlySelected) {
129 std::ranges::fill(m.vertices() | views::selected | views::colors, c);
130 }
131 else {
132 std::ranges::fill(m.vertices() | views::colors, c);
133 }
134}
135
154template<FaceMeshConcept MeshType>
156 MeshType& m,
157 Color c = Color::White,
158 bool onlySelected = false)
159{
161
162 if (onlySelected) {
163 std::ranges::fill(m.faces() | views::selected | views::colors, c);
164 }
165 else {
166 std::ranges::fill(m.faces() | views::colors, c);
167 }
168}
169
188template<EdgeMeshConcept MeshType>
190 MeshType& m,
191 Color c = Color::White,
192 bool onlySelected = false)
193{
195
196 if (onlySelected) {
197 std::ranges::fill(m.edges() | views::selected | views::colors, c);
198 }
199 else {
200 std::ranges::fill(m.edges() | views::colors, c);
201 }
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
383template<MeshConcept MeshType>
385{
386 detail::setPerElemColorFromMaterial<ElemId::VERTEX>(m);
387}
388
405template<FaceMeshConcept MeshType>
407{
408 detail::setPerElemColorFromMaterial<ElemId::FACE>(m);
409}
410
436template<FaceMeshConcept MeshType>
438 MeshType& m,
439 Color borderColor = Color::Blue,
440 Color internalColor = Color::White,
441 Color mixColor = Color::Cyan)
442{
443 requirePerVertexColor(m);
444
445 using FaceType = MeshType::FaceType;
446
447 const Color baseColor = Color::Green;
448
449 setPerVertexColor(m, baseColor);
450
451 for (FaceType& f : m.faces()) {
452 for (uint i = 0; i < f.vertexNumber(); ++i) {
453 if (f.edgeOnBorder(i)) {
454 if (f.vertex(i)->color() == baseColor)
455 f.vertex(i)->color() = borderColor;
456 if (f.vertex(i)->color() == internalColor)
457 f.vertex(i)->color() = mixColor;
458 if (f.vertexMod(i + 1)->color() == baseColor)
459 f.vertexMod(i + 1)->color() = borderColor;
460 if (f.vertexMod(i + 1)->color() == internalColor)
461 f.vertexMod(i + 1)->color() = mixColor;
462 }
463 else {
464 if (f.vertex(i)->color() == baseColor)
465 f.vertex(i)->color() = internalColor;
466 if (f.vertex(i)->color() == borderColor)
467 f.vertex(i)->color() = mixColor;
468 if (f.vertexMod(i + 1)->color() == baseColor)
469 f.vertexMod(i + 1)->color() = internalColor;
470 if (f.vertexMod(i + 1)->color() == borderColor)
471 f.vertexMod(i + 1)->color() = mixColor;
472 }
473 }
474 }
475}
476
495template<FaceMeshConcept MeshType>
497 MeshType& m,
498 const std::vector<std::set<uint>>& connectedComponents)
499{
500 std::vector<Color> vc = colorScattering(connectedComponents.size());
501
502 uint cid = 0;
503 for (const std::set<uint>& connComp : connectedComponents) {
504 for (const uint& fid : connComp) {
505 m.face(fid).color() = vc[cid];
506 }
507 cid++;
508 }
509}
510
528template<FaceMeshConcept MeshType>
537
562template<FaceMeshConcept MeshType>
564 MeshType& m,
565 uint nColors = 50,
566 bool checkFauxEdges = true)
567{
569
570 using FaceType = MeshType::FaceType;
571
572 Color baseColor = Color::Black;
573 setPerFaceColor(m, baseColor);
574
575 std::vector<Color> vc = colorScattering(nColors);
576
577 for (FaceType& f : m.faces()) {
578 if (f.color() == baseColor) {
579 f.color() = vc[m.index(f) % nColors];
580 }
581 if constexpr (HasPerFaceAdjacentFaces<MeshType>) {
583 for (uint i = 0; i < f.vertexNumber(); ++i) {
584 if (f.edgeFaux(i)) {
585 assert(f.adjFace(i) != nullptr);
586 f.adjFace(i)->color() = f.color();
587 }
588 }
589 }
590 }
591 }
592}
593
615template<MeshConcept MeshType, Point3Concept PointType>
617 MeshType& m,
618 const PointType& period,
619 const PointType& offset = PointType(0, 0, 0),
620 bool onSelected = false)
621{
622 requirePerVertexColor(m);
623
624 using VertexType = MeshType::VertexType;
625
626 PointType p[3];
627
628 for (VertexType& v : m.vertices()) {
629 if (!onSelected || v.selected()) {
630 p[0] = (v.position() / period[0]) + offset;
631 p[1] = (v.position() / period[1]) + offset;
632 p[2] = (v.position() / period[2]) + offset;
633 v.color() = Color(
634 127 + 128.0 * perlinNoise(p[0][0], p[0][1], p[0][2]),
635 127 + 128.0 * perlinNoise(p[1][0], p[1][1], p[1][2]),
636 127 + 128.0 * perlinNoise(p[2][0], p[2][1], p[2][2]),
637 255);
638 }
639 }
640}
641
660template<MeshConcept MeshType, Point3Concept PointType>
662 MeshType& m,
663 double period,
664 const PointType& offset = PointType(0, 0, 0),
665 const Color& color1 = Color::Black,
666 const Color& color2 = Color::White,
667 bool onSelected = false)
668{
669 requirePerVertexColor(m);
670
671 using VertexType = MeshType::VertexType;
672
673 for (VertexType& v : m.vertices()) {
674 if (!onSelected || v.selected()) {
675 PointType p = v.position() / period + offset;
676
677 double factor = (perlinNoise(p[0], p[1], p[2]) + 1.0) / 2.0;
678
679 int rr = (color1[0] * factor) + (color2[0] * (1.0 - factor));
680 int gg = (color1[1] * factor) + (color2[1] * (1.0 - factor));
681 int bb = (color1[2] * factor) + (color2[2] * (1.0 - factor));
682 int aa = (color1[3] * factor) + (color2[3] * (1.0 - factor));
683
684 v.color() = Color(rr, gg, bb, aa);
685 }
686 }
687}
688
689} // namespace vcl
690
691#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:791
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:431
void requirePerFaceQuality(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a Quality Component,...
Definition face_requirements.h:1250
void requirePerFaceColor(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a Color Component,...
Definition face_requirements.h:1073
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 setPerVertexColorFromMaterial(MeshType &m)
Sets the per-vertex color of a mesh according to a material assigned to each vertex.
Definition color.h:384
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:563
void setPerFaceColorFromMaterial(MeshType &m)
Sets the per-face color of a mesh according to a material assigned to each face.
Definition color.h:406
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:155
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:121
void setPerVertexPerlinColor(MeshType &m, double period, const PointType &offset=PointType(0, 0, 0), const Color &color1=Color::Black, const Color &color2=Color::White, bool onSelected=false)
Simple Perlin color mixing. color1 and color2 are mixed according the perlin noise function,...
Definition color.h:661
void setPerVertexColorPerlinNoise(MeshType &m, const PointType &period, const 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:616
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:437
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:496
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:189
constexpr detail::VerticesView vertices
A view that allows to iterate over the Vertex elements of an object.
Definition vertex.h:92