14#include <lagrange/Logger.h>
15#include <lagrange/internal/attribute_string_utils.h>
16#include <lagrange/internal/visit_attribute.h>
17#include <lagrange/utils/assert.h>
18#include <lagrange/utils/fmt/format.h>
21namespace OPENSUBDIV_VERSION {
29bool TopologyRefinerFactory<ConverterType>::resizeComponentTopology(
30 TopologyRefiner& refiner,
31 const ConverterType& conv)
33 const auto& mesh = conv.mesh;
36 int num_vertices =
static_cast<int>(mesh.get_num_vertices());
37 setNumBaseVertices(refiner, num_vertices);
40 int num_facets =
static_cast<int>(mesh.get_num_facets());
41 setNumBaseFaces(refiner, num_facets);
42 for (
int facet = 0; facet < num_facets; ++facet) {
43 int nv =
static_cast<int>(mesh.get_facet_size(facet));
44 setNumBaseFaceVertices(refiner, facet, nv);
53bool TopologyRefinerFactory<ConverterType>::assignComponentTopology(
54 TopologyRefiner& refiner,
55 const ConverterType& conv)
57 const auto& mesh = conv.mesh;
58 using Far::IndexArray;
61 int num_facets =
static_cast<int>(mesh.get_num_facets());
62 for (
int facet = 0; facet < num_facets; ++facet) {
63 IndexArray dst_facet_vertices = getBaseFaceVertices(refiner, facet);
65 auto fv = mesh.get_facet_vertices(facet);
66 for (
size_t lv = 0; lv < fv.size(); ++lv) {
67 dst_facet_vertices[lv] =
static_cast<int>(fv[lv]);
76bool TopologyRefinerFactory<ConverterType>::assignComponentTags(
77 TopologyRefiner& refiner,
78 const ConverterType& conv)
80 const auto& mesh = conv.mesh;
81 const auto& options = conv.options;
83 if (options.edge_sharpness_attr.has_value()) {
86 options.edge_sharpness_attr.value(),
88 using AttributeType = std::decay_t<decltype(attr)>;
89 using ValueType = typename AttributeType::ValueType;
90 la_runtime_assert(attr.get_num_channels() == 1);
92 std::is_floating_point_v<ValueType>,
94 "Edge sharpness attribute must use a floating point type. Received: {}",
95 lagrange::internal::value_type_name<ValueType>()));
96 la_runtime_assert(attr.get_element_type() == lagrange::AttributeElement::Edge);
97 if constexpr (AttributeType::IsIndexed) {
98 la_runtime_assert(
"Edge sharpness cannot be an indexed attribute");
100 lagrange::logger().debug(
"Using edge sharpness attribute");
101 auto values = attr.get_all();
102 for (int e = 0; e < static_cast<int>(values.size()); ++e) {
103 auto v = mesh.get_edge_vertices(e);
104 Index idx = findBaseEdge(refiner, v[0], v[1]);
106 if (idx != INDEX_INVALID) {
107 float s = static_cast<float>(ValueType(10.0) * values[e]);
108 setBaseEdgeSharpness(refiner, idx, s);
114 "Edge %d specified to be sharp does not exist (%d, %d)",
116 static_cast<int>(v[0]),
117 static_cast<int>(v[1]));
118 reportInvalidTopology(
119 Vtr::internal::Level::TOPOLOGY_INVALID_CREASE_EDGE,
128 if (options.vertex_sharpness_attr.has_value()) {
131 options.vertex_sharpness_attr.value(),
133 using AttributeType = std::decay_t<decltype(attr)>;
134 using ValueType = typename AttributeType::ValueType;
135 la_runtime_assert(attr.get_num_channels() == 1);
136 la_runtime_assert(attr.get_element_type() == lagrange::AttributeElement::Vertex);
138 std::is_floating_point_v<ValueType>,
140 "Vertex sharpness attribute must use a floating point type. Received: {}",
141 lagrange::internal::value_type_name<ValueType>()));
142 if constexpr (AttributeType::IsIndexed) {
143 la_runtime_assert(
"Vertex sharpness cannot be an indexed attribute");
145 lagrange::logger().debug(
"Using vertex sharpness attribute");
146 auto values = attr.get_all();
147 for (int v = 0; v < static_cast<int>(values.size()); ++v) {
148 float s = static_cast<float>(ValueType(10.0) * values[v]);
149 setBaseVertexSharpness(refiner, v, s);
155 if (options.face_hole_attr.has_value()) {
158 options.face_hole_attr.value(),
160 using AttributeType = std::decay_t<decltype(attr)>;
161 using ValueType = typename AttributeType::ValueType;
162 la_runtime_assert(attr.get_num_channels() == 1);
164 std::is_integral_v<ValueType>,
166 "Face holes attribute must use an integral type. Received: {}",
167 lagrange::internal::value_type_name<ValueType>()));
168 if constexpr (AttributeType::IsIndexed) {
169 la_runtime_assert(
"Face holes cannot be an indexed attribute");
171 lagrange::logger().debug(
"Using facet hole attribute");
172 auto values = attr.get_all();
173 for (int f = 0; f < static_cast<int>(values.size()); ++f) {
174 if (values[f] != ValueType(0)) {
175 lagrange::logger().debug(
"Setting facet f{} as a hole", f);
176 setBaseFaceHole(refiner, f, true);
189bool TopologyRefinerFactory<ConverterType>::assignFaceVaryingTopology(
190 TopologyRefiner& refiner,
191 const ConverterType& conv)
193 const auto& mesh = conv.mesh;
199 using AttributeType = std::decay_t<
decltype(attr)>;
200 if constexpr (!AttributeType::IsIndexed) {
204 "Face varying attributes must indexed attributes. Received: {}",
207 int num_values =
static_cast<int>(attr.values().get_num_elements());
208 auto src_indices = attr.indices().get_all();
210 int channel = createBaseFVarChannel(refiner, num_values);
212 for (
int f = 0, src_next = 0; f < static_cast<int>(mesh.get_num_facets()); ++f) {
213 IndexArray dst_indices = getBaseFaceFVarValues(refiner, f, channel);
215 for (
int lv = 0; lv < dst_indices.size(); ++lv) {
216 dst_indices[lv] = src_indices[src_next++];
227void TopologyRefinerFactory<ConverterType>::reportInvalidTopology(
230 const ConverterType& )
LA_CORE_API spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:40
uint32_t AttributeId
Identified to be used to access an attribute.
Definition AttributeFwd.h:73
#define la_runtime_assert(...)
Runtime assertion check.
Definition assert.h:177
LA_CORE_API std::string_view to_string(AttributeElement element)
Returns a string representation of an attribute element type.
Definition attribute_string_utils.cpp:22
void visit_attribute_read(const SurfaceMesh< Scalar, Index > &mesh, AttributeId id, Func &&func)
Definition visit_attribute.h:39