/* SPDX-FileCopyrightText: 2011-2024 Blender Foundation * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #ifdef WITH_OPENSUBDIV /* OpenSubdiv headers use M_PI. */ # if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES) # define _USE_MATH_DEFINES # endif # include # include # include # include # include "subd/patch.h" # include "util/types.h" # include "util/unique_ptr.h" # include "util/vector.h" CCL_NAMESPACE_BEGIN /* Directly use some OpenSubdiv namespaces for brevity. */ namespace Far = OpenSubdiv::Far; namespace Sdc = OpenSubdiv::Sdc; class Attribute; class Mesh; /* OpenSubdiv interface for vertex and attribute values. */ template struct OsdValue { T value; OsdValue() = default; void Clear(void *unused = nullptr) { (void)unused; memset((void *)&value, 0, sizeof(T)); } void AddWithWeight(OsdValue const &src, float weight) { if constexpr (std::is_same_v) { value = float3(value) + float3(src.value) * weight; } else { value += src.value * weight; } } }; /* Wrapper around Mesh for TopologyRefinerFactory. */ class OsdMesh { public: /* Face-varying attribute that requires merging of corners with the same value, typically a UV * map. The resulting topology after merging is stored in a topology refiner fvar channel. The * merged attribute values are stored here, in a generic buffer used for different data types. */ struct MergedFVar { const Attribute &attr; int channel = -1; vector values; }; Mesh &mesh; vector merged_fvars; explicit OsdMesh(Mesh &mesh) : mesh(mesh) {} Sdc::Options sdc_options(); bool use_smooth_fvar(const Attribute &attr) const; bool use_smooth_fvar() const; }; /* OpenSubdiv refiner and patch data structures. */ struct OsdData { unique_ptr refiner; unique_ptr patch_table; unique_ptr patch_map; vector> refined_verts; void build(OsdMesh &osd_mesh); }; /* Patch with OpenSubdiv evaluation. */ struct OsdPatch final : Patch { OsdData &osd_data; explicit OsdPatch(OsdData &data) : osd_data(data) {} void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, const float u, const float v) const override; }; CCL_NAMESPACE_END #endif