Blender  V3.3
topology_refiner_impl_compare.cc
Go to the documentation of this file.
1 // Copyright 2018 Blender Foundation. All rights reserved.
2 //
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software Foundation,
15 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 //
17 // Author: Sergey Sharybin
18 
20 
21 #include "internal/base/type.h"
25 
27 
28 namespace blender {
29 namespace opensubdiv {
30 namespace {
31 
32 const OpenSubdiv::Far::TopologyRefiner *getOSDTopologyRefiner(
33  const TopologyRefinerImpl *topology_refiner_impl)
34 {
35  return topology_refiner_impl->topology_refiner;
36 }
37 
38 const OpenSubdiv::Far::TopologyLevel &getOSDTopologyBaseLevel(
39  const TopologyRefinerImpl *topology_refiner_impl)
40 {
41  return getOSDTopologyRefiner(topology_refiner_impl)->GetLevel(0);
42 }
43 
45 // Quick preliminary checks.
46 
47 bool checkSchemeTypeMatches(const TopologyRefinerImpl *topology_refiner_impl,
48  const OpenSubdiv_Converter *converter)
49 {
50  const OpenSubdiv::Sdc::SchemeType converter_scheme_type =
52  return (converter_scheme_type == getOSDTopologyRefiner(topology_refiner_impl)->GetSchemeType());
53 }
54 
55 bool checkOptionsMatches(const TopologyRefinerImpl *topology_refiner_impl,
56  const OpenSubdiv_Converter *converter)
57 {
58  typedef OpenSubdiv::Sdc::Options Options;
59  const Options options = getOSDTopologyRefiner(topology_refiner_impl)->GetSchemeOptions();
60  const Options::FVarLinearInterpolation fvar_interpolation = options.GetFVarLinearInterpolation();
61  const Options::FVarLinearInterpolation converter_fvar_interpolation =
63  converter->getFVarLinearInterpolation(converter));
64  if (fvar_interpolation != converter_fvar_interpolation) {
65  return false;
66  }
67  return true;
68 }
69 
70 bool checkPreliminaryMatches(const TopologyRefinerImpl *topology_refiner_impl,
71  const OpenSubdiv_Converter *converter)
72 {
73  return checkSchemeTypeMatches(topology_refiner_impl, converter) &&
74  checkOptionsMatches(topology_refiner_impl, converter);
75 }
76 
78 // Compare attributes which affects on topology.
79 //
80 // TODO(sergey): Need to look into how auto-winding affects on face-varying
81 // indexing and, possibly, move to mesh topology as well if winding affects
82 // face-varyign as well.
83 
84 bool checkSingleUVLayerMatch(const OpenSubdiv::Far::TopologyLevel &base_level,
85  const OpenSubdiv_Converter *converter,
86  const int layer_index)
87 {
88  converter->precalcUVLayer(converter, layer_index);
89  const int num_faces = base_level.GetNumFaces();
90  // TODO(sergey): Need to check whether converter changed the winding of
91  // face to match OpenSubdiv's expectations.
92  for (int face_index = 0; face_index < num_faces; ++face_index) {
93  OpenSubdiv::Far::ConstIndexArray base_level_face_uvs = base_level.GetFaceFVarValues(
94  face_index, layer_index);
95  for (int corner = 0; corner < base_level_face_uvs.size(); ++corner) {
96  const int uv_index = converter->getFaceCornerUVIndex(converter, face_index, corner);
97  if (base_level_face_uvs[corner] != uv_index) {
98  converter->finishUVLayer(converter);
99  return false;
100  }
101  }
102  }
103  converter->finishUVLayer(converter);
104  return true;
105 }
106 
107 bool checkUVLayersMatch(const TopologyRefinerImpl *topology_refiner_impl,
108  const OpenSubdiv_Converter *converter)
109 {
110  using OpenSubdiv::Far::TopologyLevel;
111  const int num_layers = converter->getNumUVLayers(converter);
112  const TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner_impl);
113  // Number of UV layers should match.
114  if (base_level.GetNumFVarChannels() != num_layers) {
115  return false;
116  }
117  for (int layer_index = 0; layer_index < num_layers; ++layer_index) {
118  if (!checkSingleUVLayerMatch(base_level, converter, layer_index)) {
119  return false;
120  }
121  }
122  return true;
123 }
124 
125 bool checkTopologyAttributesMatch(const TopologyRefinerImpl *topology_refiner_impl,
126  const OpenSubdiv_Converter *converter)
127 {
128  return checkUVLayersMatch(topology_refiner_impl, converter);
129 }
130 
131 } // namespace
132 
134 {
135  if (!blender::opensubdiv::checkPreliminaryMatches(this, converter)) {
136  return false;
137  }
138 
139  if (!base_mesh_topology.isEqualToConverter(converter)) {
140  return false;
141  }
142 
143  // NOTE: Do after geometry check, to be sure topology does match and all
144  // indexing will go fine.
145  if (!blender::opensubdiv::checkTopologyAttributesMatch(this, converter)) {
146  return false;
147  }
148 
149  return true;
150 }
151 
152 } // namespace opensubdiv
153 } // namespace blender
bool isEqualToConverter(const OpenSubdiv_Converter *converter) const
bool isEqualToConverter(const OpenSubdiv_Converter *converter) const
CCL_NAMESPACE_BEGIN struct Options options
OpenSubdiv::Sdc::SchemeType getSchemeTypeFromCAPI(OpenSubdiv_SchemeType type)
Definition: type_convert.cc:31
OpenSubdiv::Sdc::Options::FVarLinearInterpolation getFVarLinearInterpolationFromCAPI(OpenSubdiv_FVarLinearInterpolation linear_interpolation)
Definition: type_convert.cc:45
int(* getNumUVLayers)(const struct OpenSubdiv_Converter *converter)
OpenSubdiv_FVarLinearInterpolation(* getFVarLinearInterpolation)(const struct OpenSubdiv_Converter *converter)
OpenSubdiv_SchemeType(* getSchemeType)(const struct OpenSubdiv_Converter *converter)
void(* finishUVLayer)(const struct OpenSubdiv_Converter *converter)
void(* precalcUVLayer)(const struct OpenSubdiv_Converter *converter, const int layer_index)
int(* getFaceCornerUVIndex)(const struct OpenSubdiv_Converter *converter, const int face_index, const int corner_index)