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