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 {
27bool TopologyRefinerFactory<ConverterType>::resizeComponentTopology(
28 TopologyRefiner& refiner,
29 const ConverterType& conv)
31 const auto& mesh = conv.mesh;
34 int num_vertices =
static_cast<int>(mesh.get_num_vertices());
35 setNumBaseVertices(refiner, num_vertices);
38 int num_facets =
static_cast<int>(mesh.get_num_facets());
39 setNumBaseFaces(refiner, num_facets);
40 for (
int facet = 0; facet < num_facets; ++facet) {
41 int nv =
static_cast<int>(mesh.get_facet_size(facet));
42 setNumBaseFaceVertices(refiner, facet, nv);
51bool TopologyRefinerFactory<ConverterType>::assignComponentTopology(
52 TopologyRefiner& refiner,
53 const ConverterType& conv)
55 const auto& mesh = conv.mesh;
56 using Far::IndexArray;
59 int num_facets =
static_cast<int>(mesh.get_num_facets());
60 for (
int facet = 0; facet < num_facets; ++facet) {
61 IndexArray dst_facet_vertices = getBaseFaceVertices(refiner, facet);
63 auto fv = mesh.get_facet_vertices(facet);
64 for (
size_t lv = 0; lv < fv.size(); ++lv) {
65 dst_facet_vertices[lv] =
static_cast<int>(fv[lv]);
74bool TopologyRefinerFactory<ConverterType>::assignComponentTags(
75 TopologyRefiner& refiner,
76 const ConverterType& conv)
78 const auto& mesh = conv.mesh;
79 const auto& options = conv.options;
81 if (options.edge_sharpness_attr.has_value()) {
84 options.edge_sharpness_attr.value(),
86 using AttributeType = std::decay_t<decltype(attr)>;
87 using ValueType = typename AttributeType::ValueType;
88 la_runtime_assert(attr.get_num_channels() == 1);
90 std::is_floating_point_v<ValueType>,
92 "Edge sharpness attribute must use a floating point type. Received: {}",
93 lagrange::internal::value_type_name<ValueType>()));
94 la_runtime_assert(attr.get_element_type() == lagrange::AttributeElement::Edge);
95 if constexpr (AttributeType::IsIndexed) {
96 la_runtime_assert(
"Edge sharpness cannot be an indexed attribute");
98 lagrange::logger().debug(
"Using edge sharpness attribute");
99 auto values = attr.get_all();
100 for (int e = 0; e < static_cast<int>(values.size()); ++e) {
101 auto v = mesh.get_edge_vertices(e);
102 Index idx = findBaseEdge(refiner, v[0], v[1]);
104 if (idx != INDEX_INVALID) {
105 float s = static_cast<float>(ValueType(10.0) * values[e]);
106 setBaseEdgeSharpness(refiner, idx, s);
112 "Edge %d specified to be sharp does not exist (%d, %d)",
114 static_cast<int>(v[0]),
115 static_cast<int>(v[1]));
116 reportInvalidTopology(
117 Vtr::internal::Level::TOPOLOGY_INVALID_CREASE_EDGE,
126 if (options.vertex_sharpness_attr.has_value()) {
129 options.vertex_sharpness_attr.value(),
131 using AttributeType = std::decay_t<decltype(attr)>;
132 using ValueType = typename AttributeType::ValueType;
133 la_runtime_assert(attr.get_num_channels() == 1);
134 la_runtime_assert(attr.get_element_type() == lagrange::AttributeElement::Vertex);
136 std::is_floating_point_v<ValueType>,
138 "Vertex sharpness attribute must use a floating point type. Received: {}",
139 lagrange::internal::value_type_name<ValueType>()));
140 if constexpr (AttributeType::IsIndexed) {
141 la_runtime_assert(
"Vertex sharpness cannot be an indexed attribute");
143 lagrange::logger().debug(
"Using vertex sharpness attribute");
144 auto values = attr.get_all();
145 for (int v = 0; v < static_cast<int>(values.size()); ++v) {
146 float s = static_cast<float>(ValueType(10.0) * values[v]);
147 setBaseVertexSharpness(refiner, v, s);
153 if (options.face_hole_attr.has_value()) {
156 options.face_hole_attr.value(),
158 using AttributeType = std::decay_t<decltype(attr)>;
159 using ValueType = typename AttributeType::ValueType;
160 la_runtime_assert(attr.get_num_channels() == 1);
162 std::is_integral_v<ValueType>,
164 "Face holes attribute must use an integral type. Received: {}",
165 lagrange::internal::value_type_name<ValueType>()));
166 if constexpr (AttributeType::IsIndexed) {
167 la_runtime_assert(
"Face holes cannot be an indexed attribute");
169 lagrange::logger().debug(
"Using facet hole attribute");
170 auto values = attr.get_all();
171 for (int f = 0; f < static_cast<int>(values.size()); ++f) {
172 if (values[f] != ValueType(0)) {
173 lagrange::logger().debug(
"Setting facet f{} as a hole", f);
174 setBaseFaceHole(refiner, f, true);
187bool TopologyRefinerFactory<ConverterType>::assignFaceVaryingTopology(
188 TopologyRefiner& refiner,
189 const ConverterType& conv)
191 const auto& mesh = conv.mesh;
197 using AttributeType = std::decay_t<
decltype(attr)>;
198 if constexpr (!AttributeType::IsIndexed) {
202 "Face varying attributes must indexed attributes. Received: {}",
205 int num_values =
static_cast<int>(attr.values().get_num_elements());
206 auto src_indices = attr.indices().get_all();
208 int channel = createBaseFVarChannel(refiner, num_values);
210 for (
int f = 0, src_next = 0; f < static_cast<int>(mesh.get_num_facets()); ++f) {
211 IndexArray dst_indices = getBaseFaceFVarValues(refiner, f, channel);
213 for (
int lv = 0; lv < dst_indices.size(); ++lv) {
214 dst_indices[lv] = src_indices[src_next++];
225void TopologyRefinerFactory<ConverterType>::reportInvalidTopology(
228 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:175
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