Blender V5.0
topology_refiner_impl_compare.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2018 Blender Foundation
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 *
5 * Author: Sergey Sharybin. */
6
9
12
13namespace blender::opensubdiv {
14
15static const OpenSubdiv::Far::TopologyRefiner *getOSDTopologyRefiner(
16 const TopologyRefinerImpl *topology_refiner_impl)
17{
18 return topology_refiner_impl->topology_refiner;
19}
20
21static const OpenSubdiv::Far::TopologyLevel &getOSDTopologyBaseLevel(
22 const TopologyRefinerImpl *topology_refiner_impl)
23{
24 return getOSDTopologyRefiner(topology_refiner_impl)->GetLevel(0);
25}
26
28// Quick preliminary checks.
29
30static bool checkSchemeTypeMatches(const TopologyRefinerImpl *topology_refiner_impl,
31 const OpenSubdiv_Converter *converter)
32{
33 const OpenSubdiv::Sdc::SchemeType converter_scheme_type =
35 return (converter_scheme_type == getOSDTopologyRefiner(topology_refiner_impl)->GetSchemeType());
36}
37
38static bool checkOptionsMatches(const TopologyRefinerImpl *topology_refiner_impl,
39 const OpenSubdiv_Converter *converter)
40{
41 using Options = OpenSubdiv::Sdc::Options;
42 const Options options = getOSDTopologyRefiner(topology_refiner_impl)->GetSchemeOptions();
43 const Options::FVarLinearInterpolation fvar_interpolation = options.GetFVarLinearInterpolation();
44 const Options::FVarLinearInterpolation converter_fvar_interpolation =
46 converter->getFVarLinearInterpolation(converter));
47 if (fvar_interpolation != converter_fvar_interpolation) {
48 return false;
49 }
50 return true;
51}
52
53static bool checkPreliminaryMatches(const TopologyRefinerImpl *topology_refiner_impl,
54 const OpenSubdiv_Converter *converter)
55{
56 return checkSchemeTypeMatches(topology_refiner_impl, converter) &&
57 checkOptionsMatches(topology_refiner_impl, converter);
58}
59
61// Compare attributes which affects on topology.
62//
63// TODO(sergey): Need to look into how auto-winding affects on face-varying
64// indexing and, possibly, move to mesh topology as well if winding affects
65// face-varyign as well.
66
67static bool checkSingleUVLayerMatch(const OpenSubdiv::Far::TopologyLevel &base_level,
68 const OpenSubdiv_Converter *converter,
69 const int layer_index)
70{
71 converter->precalcUVLayer(converter, layer_index);
72 const int num_faces = base_level.GetNumFaces();
73 // TODO(sergey): Need to check whether converter changed the winding of
74 // face to match OpenSubdiv's expectations.
75 for (int face_index = 0; face_index < num_faces; ++face_index) {
76 OpenSubdiv::Far::ConstIndexArray base_level_face_uvs = base_level.GetFaceFVarValues(
77 face_index, layer_index);
78 for (int corner = 0; corner < base_level_face_uvs.size(); ++corner) {
79 const int uv_index = converter->getFaceCornerUVIndex(converter, face_index, corner);
80 if (base_level_face_uvs[corner] != uv_index) {
81 converter->finishUVLayer(converter);
82 return false;
83 }
84 }
85 }
86 converter->finishUVLayer(converter);
87 return true;
88}
89
90static bool checkUVLayersMatch(const TopologyRefinerImpl *topology_refiner_impl,
91 const OpenSubdiv_Converter *converter)
92{
93 using OpenSubdiv::Far::TopologyLevel;
94 const int num_layers = converter->getNumUVLayers(converter);
95 const TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner_impl);
96 // Number of UV layers should match.
97 if (base_level.GetNumFVarChannels() != num_layers) {
98 return false;
99 }
100 for (int layer_index = 0; layer_index < num_layers; ++layer_index) {
101 if (!checkSingleUVLayerMatch(base_level, converter, layer_index)) {
102 return false;
103 }
104 }
105 return true;
106}
107
108static bool checkTopologyAttributesMatch(const TopologyRefinerImpl *topology_refiner_impl,
109 const OpenSubdiv_Converter *converter)
110{
111 return checkUVLayersMatch(topology_refiner_impl, converter);
112}
113
115{
116 if (!blender::opensubdiv::checkPreliminaryMatches(this, converter)) {
117 return false;
118 }
119
120 if (!base_mesh_topology.isEqualToConverter(converter)) {
121 return false;
122 }
123
124 // NOTE: Do after geometry check, to be sure topology does match and all
125 // indexing will go fine.
127 return false;
128 }
129
130 return true;
131}
132
133} // namespace blender::opensubdiv
OpenSubdiv::Far::TopologyRefiner * topology_refiner
bool isEqualToConverter(const OpenSubdiv_Converter *converter) const
CCL_NAMESPACE_BEGIN struct Options options
static const OpenSubdiv::Far::TopologyLevel & getOSDTopologyBaseLevel(const TopologyRefinerImpl *topology_refiner_impl)
static bool checkPreliminaryMatches(const TopologyRefinerImpl *topology_refiner_impl, const OpenSubdiv_Converter *converter)
static bool checkUVLayersMatch(const TopologyRefinerImpl *topology_refiner_impl, const OpenSubdiv_Converter *converter)
static const OpenSubdiv::Far::TopologyRefiner * getOSDTopologyRefiner(const TopologyRefinerImpl *topology_refiner_impl)
static bool checkOptionsMatches(const TopologyRefinerImpl *topology_refiner_impl, const OpenSubdiv_Converter *converter)
OpenSubdiv::Sdc::SchemeType getSchemeTypeFromCAPI(OpenSubdiv_SchemeType type)
static bool checkSchemeTypeMatches(const TopologyRefinerImpl *topology_refiner_impl, const OpenSubdiv_Converter *converter)
static bool checkTopologyAttributesMatch(const TopologyRefinerImpl *topology_refiner_impl, const OpenSubdiv_Converter *converter)
OpenSubdiv::Sdc::Options::FVarLinearInterpolation getFVarLinearInterpolationFromCAPI(OpenSubdiv_FVarLinearInterpolation linear_interpolation)
static bool checkSingleUVLayerMatch(const OpenSubdiv::Far::TopologyLevel &base_level, const OpenSubdiv_Converter *converter, const int layer_index)
int(* getFaceCornerUVIndex)(const OpenSubdiv_Converter *converter, const int face_index, const int corner_index)
void(* precalcUVLayer)(const OpenSubdiv_Converter *converter, const int layer_index)
OpenSubdiv_FVarLinearInterpolation(* getFVarLinearInterpolation)(const OpenSubdiv_Converter *converter)
int(* getNumUVLayers)(const OpenSubdiv_Converter *converter)
OpenSubdiv_SchemeType(* getSchemeType)(const OpenSubdiv_Converter *converter)
void(* finishUVLayer)(const OpenSubdiv_Converter *converter)