14#include <lagrange/Logger.h>
15#include <lagrange/SurfaceMesh.h>
16#include <lagrange/foreach_attribute.h>
19#include <lagrange/utils/warnoff.h>
20#include <polyscope/polyscope.h>
21#include <polyscope/point_cloud.h>
22#include <polyscope/surface_mesh.h>
23#include <polyscope/curve_network.h>
24#include <lagrange/utils/warnon.h>
27namespace lagrange::polyscope {
38 default:
return false;
46 default: return ::polyscope::VectorType::STANDARD;
51template <
typename ValueType>
52auto as_color_matrix(
const lagrange::Attribute<ValueType>& attr) ->
decltype(
auto)
57 .unaryExpr([&](
float x) {
return std::is_floating_point_v<ValueType> ? x : x / 255.f; })
59 .unaryExpr([](
float x) {
61 return std::pow(x, gamma);
65template <
typename PolyscopeStructure>
68 using PolyscopeType = std::decay_t<PolyscopeStructure>;
69 static constexpr bool IsMesh = std::is_same_v<PolyscopeType, ::polyscope::SurfaceMesh>;
70 static constexpr bool IsEdge = std::is_same_v<PolyscopeType, ::polyscope::CurveNetwork>;
72 using QuantityType = std::conditional_t<
74 ::polyscope::SurfaceMeshQuantity,
77 ::polyscope::CurveNetworkQuantity,
78 ::polyscope::PointCloudQuantity>>;
81template <
typename PolyscopeStructure>
82using QuantityType =
typename PolyscopeTrait<PolyscopeStructure>::QuantityType;
85template <
typename PolyscopeStructure,
typename ValueType>
86auto register_attribute(
87 PolyscopeStructure* ps_struct,
88 std::string_view name_,
92 std::string name(name_);
94 using PolyscopeType = std::decay_t<PolyscopeStructure>;
95 constexpr bool IsMesh = std::is_same_v<PolyscopeType, ::polyscope::SurfaceMesh>;
96 constexpr bool IsEdge = std::is_same_v<PolyscopeType, ::polyscope::CurveNetwork>;
98 switch (attr.get_element_type()) {
100 if (attr.get_usage() == Usage::Scalar) {
102 if constexpr (IsMesh) {
103 return ps_struct->addVertexScalarQuantity(name,
vector_view(attr));
104 }
else if constexpr (IsEdge) {
105 return ps_struct->addNodeScalarQuantity(name,
vector_view(attr));
107 return ps_struct->addScalarQuantity(name,
vector_view(attr));
109 }
else if (attr.get_num_channels() == 3) {
110 if (show_as_vector(attr.get_usage())) {
112 ::polyscope::VectorType vt = vector_type(attr.get_usage());
113 if constexpr (IsMesh) {
114 return ps_struct->addVertexVectorQuantity(name,
matrix_view(attr), vt);
115 }
else if constexpr (IsEdge) {
116 return ps_struct->addNodeVectorQuantity(name,
matrix_view(attr), vt);
118 return ps_struct->addVectorQuantity(name,
matrix_view(attr), vt);
120 }
else if (attr.get_usage() == Usage::Color) {
122 if constexpr (IsMesh) {
123 return ps_struct->addVertexColorQuantity(name, as_color_matrix(attr));
124 }
else if constexpr (IsEdge) {
125 return ps_struct->addNodeColorQuantity(name, as_color_matrix(attr));
127 return ps_struct->addColorQuantity(name, as_color_matrix(attr));
130 }
else if (attr.get_num_channels() == 2) {
131 if (show_as_vector(attr.get_usage())) {
132 lagrange::logger().info(
"Registering 2D vector vertex attribute: {}", name);
133 ::polyscope::VectorType vt = vector_type(attr.get_usage());
134 if constexpr (IsMesh) {
135 return ps_struct->addVertexVectorQuantity2D(name,
matrix_view(attr), vt);
136 }
else if constexpr (IsEdge) {
137 return ps_struct->addNodeVectorQuantity2D(name,
matrix_view(attr), vt);
139 return ps_struct->addVectorQuantity2D(name,
matrix_view(attr), vt);
142 }
else if (attr.get_usage() == Usage::UV && attr.get_num_channels() == 2) {
143 if constexpr (IsMesh) {
145 return ps_struct->addVertexParameterizationQuantity(name,
matrix_view(attr));
152 if (attr.get_usage() == Usage::Scalar) {
154 if constexpr (IsMesh) {
155 return ps_struct->addFaceScalarQuantity(name,
vector_view(attr));
156 }
else if constexpr (IsEdge) {
157 return ps_struct->addEdgeScalarQuantity(name,
vector_view(attr));
159 }
else if (attr.get_num_channels() == 3) {
160 if (show_as_vector(attr.get_usage())) {
162 ::polyscope::VectorType vt = vector_type(attr.get_usage());
163 if constexpr (IsMesh) {
164 return ps_struct->addFaceVectorQuantity(name,
matrix_view(attr), vt);
165 }
else if constexpr (IsEdge) {
166 return ps_struct->addEdgeVectorQuantity(name,
matrix_view(attr), vt);
168 }
else if (attr.get_usage() == Usage::Color) {
170 if constexpr (IsMesh) {
171 return ps_struct->addFaceColorQuantity(name, as_color_matrix(attr));
172 }
else if constexpr (IsEdge) {
173 return ps_struct->addEdgeColorQuantity(name, as_color_matrix(attr));
176 }
else if (attr.get_num_channels() == 2) {
177 if (show_as_vector(attr.get_usage())) {
179 ::polyscope::VectorType vt = vector_type(attr.get_usage());
180 if constexpr (IsMesh) {
181 return ps_struct->addFaceVectorQuantity2D(name,
matrix_view(attr), vt);
182 }
else if constexpr (IsEdge) {
183 return ps_struct->addEdgeVectorQuantity2D(name,
matrix_view(attr), vt);
189 if constexpr (IsMesh) {
190 if (attr.get_usage() == Usage::Scalar) {
192 return ps_struct->addEdgeScalarQuantity(name,
vector_view(attr));
197 if constexpr (IsMesh) {
198 if (attr.get_usage() == Usage::UV && attr.get_num_channels() == 2) {
200 return ps_struct->addParameterizationQuantity(name,
matrix_view(attr));
210template <
typename PolyscopeStructure,
typename Scalar,
typename Index>
211void register_attributes(PolyscopeStructure* ps_struct,
const SurfaceMesh<Scalar, Index>& mesh)
218 using AttributeType = std::decay_t<
decltype(attr)>;
219 if constexpr (!AttributeType::IsIndexed) {
220 if (!register_attribute(ps_struct, name, attr)) {
Derived attribute class that stores the actual information.
Definition Attribute.h:153
static bool attr_name_is_reserved(std::string_view name)
Check whether the given name corresponds to a reserved attribute.
Definition SurfaceMesh.cpp:1416
LA_CORE_API spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:40
AttributeUsage
Usage tag indicating how the attribute should behave under mesh transformations.
Definition AttributeFwd.h:54
@ Position
Mesh attribute must have exactly dim channels.
Definition AttributeFwd.h:57
@ Tangent
Mesh attribute can have dim or dim + 1 channels.
Definition AttributeFwd.h:59
@ Vector
Mesh attribute can have any number of channels (including 1 channel).
Definition AttributeFwd.h:55
@ Normal
Mesh attribute can have dim or dim + 1 channels.
Definition AttributeFwd.h:58
@ Bitangent
Mesh attribute can have dim or dim + 1 channels.
Definition AttributeFwd.h:60
@ Edge
Per-edge mesh attributes.
Definition AttributeFwd.h:34
@ Facet
Per-facet mesh attributes.
Definition AttributeFwd.h:31
@ Corner
Per-corner mesh attributes.
Definition AttributeFwd.h:37
@ Vertex
Per-vertex mesh attributes.
Definition AttributeFwd.h:28
void seq_foreach_named_attribute_read(const SurfaceMesh< Scalar, Index > &mesh, Visitor &&vis)
Applies a function to each attribute of a mesh.
Definition foreach_attribute.h:208
SurfaceMesh< ToScalar, ToIndex > cast(const SurfaceMesh< FromScalar, FromIndex > &source_mesh, const AttributeFilter &convertible_attributes={}, std::vector< std::string > *converted_attributes_names=nullptr)
Cast a mesh to a mesh of different scalar and/or index type.
ConstRowMatrixView< ValueType > matrix_view(const Attribute< ValueType > &attribute)
Returns a read-only view of a given attribute in the form of an Eigen matrix.
Definition views.cpp:35
ConstVectorView< ValueType > vector_view(const Attribute< ValueType > &attribute)
Returns a read-only view of a scalar attribute in the form of an Eigen vector.
Definition views.cpp:51
Definition register_attributes.h:67