Visual Computing Library
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#include <vclib/math/perlin_noise.h>
28#include <vclib/mesh/requirements.h>
29#include <vclib/space/core/color.h>
30#include <vclib/views/mesh.h>
31
32#include <set>
33
34namespace vcl {
35
36namespace detail {
37
38struct ColorAvgInfo
39{
40 Point4<uint> c;
41 uint cnt = 0;
42};
43
44template<uint ELEM_ID, FaceMeshConcept MeshType>
45void setPerElemColorFromVertexColor(MeshType& m)
46{
47 requirePerVertexColor(m);
48 requirePerElementComponent<ELEM_ID, CompId::COLOR>(m);
49
50 using VertexType = MeshType::VertexType;
51
52 for (auto& f : m.template elements<ELEM_ID>()) {
53 Point4<uint> avg(0, 0, 0, 0);
54 for (const VertexType* v : f.vertices()) {
55 avg += v->color().template cast<uint>();
56 }
57 avg /= f.vertexNumber();
58 f.color() = avg.cast<uint8_t>();
59 }
60}
61
62} // namespace detail
63
81template<MeshConcept MeshType>
83 MeshType& m,
84 Color c = Color::White,
85 bool onlySelected = false)
86{
87 requirePerVertexColor(m);
88
89 if (onlySelected) {
90 std::ranges::fill(m.vertices() | views::selected | views::colors, c);
91 }
92 else {
93 std::ranges::fill(m.vertices() | views::colors, c);
94 }
95}
96
115template<FaceMeshConcept MeshType>
117 MeshType& m,
118 Color c = Color::White,
119 bool onlySelected = false)
120{
122
123 if (onlySelected) {
124 std::ranges::fill(m.faces() | views::selected | views::colors, c);
125 }
126 else {
127 std::ranges::fill(m.faces() | views::colors, c);
128 }
129}
130
149template<EdgeMeshConcept MeshType>
151 MeshType& m,
152 Color c = Color::White,
153 bool onlySelected = false)
154{
156
157 if (onlySelected) {
158 std::ranges::fill(m.edges() | views::selected | views::colors, c);
159 }
160 else {
161 std::ranges::fill(m.edges() | views::colors, c);
162 }
163}
164
176template<HasColor MeshType>
177void setMeshColor(MeshType& m, Color c = Color::White)
178{
179 m.color() = c;
180}
181
198template<FaceMeshConcept MeshType>
200{
201 requirePerVertexColor(m);
203
204 using VertexType = MeshType::VertexType;
205 using FaceType = MeshType::FaceType;
206
207 std::vector<detail::ColorAvgInfo> csi(m.vertexContainerSize());
208
209 for (const FaceType& f : m.faces()) {
210 for (const VertexType* v : f.vertices()) {
211 csi[m.index(v)].c += v->color();
212 csi[m.index(v)].cnt++;
213 }
214 }
215
216 for (VertexType& v : m.vertices()) {
217 v.color() = csi[m.index(v)].c / csi[m.index(v)].cnt;
218 }
219}
220
237template<FaceMeshConcept MeshType>
239{
240 detail::setPerElemColorFromVertexColor<ElemId::FACE>(m);
241}
242
259template<EdgeMeshConcept MeshType>
261{
262 detail::setPerElemColorFromVertexColor<ElemId::EDGE>(m);
263}
264
289template<MeshConcept MeshType>
291 MeshType& m,
292 Color::ColorMap colorMap = Color::ColorMap::RedBlue,
293 typename MeshType::VertexType::QualityType minQuality = 0,
294 typename MeshType::VertexType::QualityType maxQuality = 0)
295{
296 requirePerVertexColor(m);
297 requirePerVertexQuality(m);
298
299 using VertexType = MeshType::VertexType;
300 using QualityType = VertexType::QualityType;
301
302 if (minQuality == maxQuality) {
303 std::pair<QualityType, QualityType> pair = vertexQualityMinMax(m);
304 minQuality = pair.first;
305 maxQuality = pair.second;
306 }
307 for (VertexType& v : m.vertices()) {
308 v.color() =
309 colorFromInterval(minQuality, maxQuality, v.quality(), colorMap);
310 }
311}
312
337template<FaceMeshConcept MeshType>
339 MeshType& m,
340 Color::ColorMap colorMap = Color::ColorMap::RedBlue,
341 typename MeshType::FaceType::QualityType minQuality = 0,
342 typename MeshType::FaceType::QualityType maxQuality = 0)
343{
346
347 using FaceType = MeshType::FaceType;
348 using QualityType = FaceType::QualityType;
349
350 if (minQuality == maxQuality) {
351 std::pair<QualityType, QualityType> pair = faceQualityMinMax(m);
352
353 minQuality = pair.first;
354 maxQuality = pair.second;
355 }
356 for (FaceType& f : m.faces()) {
357 f.color() =
358 colorFromInterval(minQuality, maxQuality, f.quality(), colorMap);
359 }
360}
361
387template<FaceMeshConcept MeshType>
389 MeshType& m,
390 Color borderColor = Color::Blue,
391 Color internalColor = Color::White,
392 Color mixColor = Color::Cyan)
393{
394 requirePerVertexColor(m);
395
396 using FaceType = MeshType::FaceType;
397
398 const Color baseColor = Color::Green;
399
401
402 for (FaceType& f : m.faces()) {
403 for (uint i = 0; i < f.vertexNumber(); ++i) {
404 if (f.edgeOnBorder(i)) {
405 if (f.vertex(i).color() == baseColor)
406 f.vertex(i).color() = borderColor;
407 if (f.vertex(i).color() == internalColor)
408 f.vertex(i).color() = mixColor;
409 if (f.vertexMod(i + 1).color() == baseColor)
410 f.vertexMod(i + 1).color() = borderColor;
411 if (f.vertexMod(i + 1).color() == internalColor)
412 f.vertexMod(i + 1).color() = mixColor;
413 }
414 else {
415 if (f.vertex(i).color() == baseColor)
416 f.vertex(i).color() = internalColor;
417 if (f.vertex(i).color() == borderColor)
418 f.vertex(i).color() = mixColor;
419 if (f.vertexMod(i + 1).color() == baseColor)
420 f.vertexMod(i + 1).color() = internalColor;
421 if (f.vertexMod(i + 1).color() == borderColor)
422 f.vertexMod(i + 1).color() = mixColor;
423 }
424 }
425 }
426}
427
446template<FaceMeshConcept MeshType>
448 MeshType& m,
449 const std::vector<std::set<uint>>& connectedComponents)
450{
451 std::vector<Color> vc = colorScattering(connectedComponents.size());
452
453 uint cid = 0;
454 for (const std::set<uint>& connComp : connectedComponents) {
455 for (const uint& fid : connComp) {
456 m.face(fid).color() = vc[cid];
457 }
458 cid++;
459 }
460}
461
479template<FaceMeshConcept MeshType>
488
513template<FaceMeshConcept MeshType>
515 MeshType& m,
516 uint nColors = 50,
517 bool checkFauxEdges = true)
518{
520
521 using FaceType = MeshType::FaceType;
522
523 Color baseColor = Color::Black;
525
526 std::vector<Color> vc = colorScattering(nColors);
527
528 for (FaceType& f : m.faces()) {
529 if (f.color() == baseColor) {
530 f.color() = vc[m.index(f) % nColors];
531 }
532 if constexpr (HasPerFaceAdjacentFaces<MeshType>) {
534 for (uint i = 0; i < f.vertexNumber(); ++i) {
535 if (f.edgeFaux(i)) {
536 assert(f.adjFace(i) != nullptr);
537 f.adjFace(i)->color = f.color();
538 }
539 }
540 }
541 }
542 }
543}
544
566template<MeshConcept MeshType, PointConcept PointType>
568 MeshType& m,
569 PointType period,
570 PointType offset = PointType(0, 0, 0),
571 bool onSelected = false)
572{
573 requirePerVertexColor(m);
574
575 using VertexType = MeshType::VertexType;
576
577 PointType p[3];
578
579 for (VertexType& v : m.vertices()) {
580 if (!onSelected || v.selected()) {
581 p[0] = (v.coord() / period[0]) + offset;
582 p[1] = (v.coord() / period[1]) + offset;
583 p[2] = (v.coord() / period[2]) + offset;
584 v.color() = Color(
585 127 + 128.0 * perlinNoise(p[0][0], p[0][1], p[0][2]),
586 127 + 128.0 * perlinNoise(p[1][0], p[1][1], p[1][2]),
587 127 + 128.0 * perlinNoise(p[2][0], p[2][1], p[2][2]),
588 255);
589 }
590 }
591}
592
611template<MeshConcept MeshType, PointConcept PointType>
613 MeshType& m,
614 double period,
615 PointType offset = PointType(0, 0, 0),
616 Color color1 = Color::Black,
617 Color color2 = Color::White,
618 bool onSelected = false)
619{
620 requirePerVertexColor(m);
621
622 using VertexType = MeshType::VertexType;
623
624 for (VertexType& v : m.vertices()) {
625 if (!onSelected || v.selected()) {
626 PointType p = v.coord() / period + offset;
627
628 double factor = (perlinNoise(p[0], p[1], p[2]) + 1.0) / 2.0;
629
630 int rr = (color1[0] * factor) + (color2[0] * (1.0 - factor));
631 int gg = (color1[1] * factor) + (color2[1] * (1.0 - factor));
632 int bb = (color1[2] * factor) + (color2[2] * (1.0 - factor));
633 int aa = (color1[3] * factor) + (color2[3] * (1.0 - factor));
634
635 v.color() = Color(rr, gg, bb, aa);
636 }
637 }
638}
639
640} // namespace vcl
641
642#endif // VCL_ALGORITHMS_MESH_UPDATE_COLOR_H
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:123
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
Concept that checks if a Mesh has the per Face AdjacentFaces component.
Definition per_face.h:79
std::vector< std::set< uint > > connectedComponents(const MeshType &m)
Computes the connected components of the input mesh based on its topology.
Definition clean.h:650
void requirePerEdgeColor(const MeshType &m)
This function asserts that a Mesh has a EdgeContainer, the Edge has a Color Component,...
Definition edge_requirements.h:548
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:153
void requirePerFaceQuality(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a Quality Component,...
Definition face_requirements.h:875
void requirePerFaceColor(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a Color Component,...
Definition face_requirements.h:734
void setPerVertexColorFromFaceColor(MeshType &m)
Sets the vertex colors from its incident face colors, computing a plain average of the face colors.
Definition color.h:199
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:514
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 coordinates.
Definition color.h:567
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:612
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:116
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:290
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:338
void setPerFaceColorFromVertexColor(MeshType &m)
Sets the face colors from its incident vertex colors, computing a plain average of the vertex colors.
Definition color.h:238
void setPerEdgeColorFromVertexColor(MeshType &m)
Sets the edge colors from its incident vertex colors, computing a plain average of the vertex colors.
Definition color.h:260
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:82
void setMeshColor(MeshType &m, Color c=Color::White)
Sets the color component of a mesh.
Definition color.h:177
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:388
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:447
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:150
constexpr detail::VerticesView vertices
A view that allows to iterate over the Vertex elements of an object.
Definition vertex.h:60