Blender  V2.93
topology_refiner_capi.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 "MEM_guardedalloc.h"
24 
26 
27 namespace {
28 
29 const OpenSubdiv::Far::TopologyRefiner *getOSDTopologyRefiner(
30  const OpenSubdiv_TopologyRefiner *topology_refiner)
31 {
32  return topology_refiner->impl->topology_refiner;
33 }
34 
35 const OpenSubdiv::Far::TopologyLevel &getOSDTopologyBaseLevel(
36  const OpenSubdiv_TopologyRefiner *topology_refiner)
37 {
38  return getOSDTopologyRefiner(topology_refiner)->GetLevel(0);
39 }
40 
41 int getSubdivisionLevel(const OpenSubdiv_TopologyRefiner *topology_refiner)
42 {
43  return topology_refiner->impl->settings.level;
44 }
45 
46 bool getIsAdaptive(const OpenSubdiv_TopologyRefiner *topology_refiner)
47 {
48  return topology_refiner->impl->settings.is_adaptive;
49 }
50 
52 // Query basic topology information from base level.
53 
54 int getNumVertices(const OpenSubdiv_TopologyRefiner *topology_refiner)
55 {
56  return getOSDTopologyBaseLevel(topology_refiner).GetNumVertices();
57 }
58 
59 int getNumEdges(const OpenSubdiv_TopologyRefiner *topology_refiner)
60 {
61  return getOSDTopologyBaseLevel(topology_refiner).GetNumEdges();
62 }
63 
64 int getNumFaces(const OpenSubdiv_TopologyRefiner *topology_refiner)
65 {
66  return getOSDTopologyBaseLevel(topology_refiner).GetNumFaces();
67 }
68 
70 // PTex face geometry queries.
71 
72 static void convertArrayToRaw(const OpenSubdiv::Far::ConstIndexArray &array, int *raw_array)
73 {
74  for (int i = 0; i < array.size(); ++i) {
75  raw_array[i] = array[i];
76  }
77 }
78 
79 int getNumFaceVertices(const OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index)
80 {
81  const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner);
82  return base_level.GetFaceVertices(face_index).size();
83 }
84 
85 void getFaceVertices(const OpenSubdiv_TopologyRefiner *topology_refiner,
86  const int face_index,
87  int *face_vertices_indices)
88 {
89  const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner);
90  OpenSubdiv::Far::ConstIndexArray array = base_level.GetFaceVertices(face_index);
91  convertArrayToRaw(array, face_vertices_indices);
92 }
93 
94 int getNumFaceEdges(const OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index)
95 {
96  const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner);
97  return base_level.GetFaceEdges(face_index).size();
98 }
99 
100 void getFaceEdges(const OpenSubdiv_TopologyRefiner *topology_refiner,
101  const int face_index,
102  int *face_edges_indices)
103 {
104  const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner);
105  OpenSubdiv::Far::ConstIndexArray array = base_level.GetFaceEdges(face_index);
106  convertArrayToRaw(array, face_edges_indices);
107 }
108 
109 void getEdgeVertices(const OpenSubdiv_TopologyRefiner *topology_refiner,
110  const int edge_index,
111  int edge_vertices_indices[2])
112 {
113  const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner);
114  OpenSubdiv::Far::ConstIndexArray array = base_level.GetEdgeVertices(edge_index);
115  assert(array.size() == 2);
116  edge_vertices_indices[0] = array[0];
117  edge_vertices_indices[1] = array[1];
118 }
119 
120 int getNumVertexEdges(const OpenSubdiv_TopologyRefiner *topology_refiner, const int vertex_index)
121 {
122  const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner);
123  return base_level.GetVertexEdges(vertex_index).size();
124 }
125 
126 void getVertexEdges(const OpenSubdiv_TopologyRefiner *topology_refiner,
127  const int vertex_index,
128  int *vertex_edges_indices)
129 {
130  const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner);
131  OpenSubdiv::Far::ConstIndexArray array = base_level.GetVertexEdges(vertex_index);
132  convertArrayToRaw(array, vertex_edges_indices);
133 }
134 
135 int getNumFacePtexFaces(const OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index)
136 {
137  const int num_face_vertices = topology_refiner->getNumFaceVertices(topology_refiner, face_index);
138  if (num_face_vertices == 4) {
139  return 1;
140  }
141  else {
142  return num_face_vertices;
143  }
144 }
145 
146 int getNumPtexFaces(const OpenSubdiv_TopologyRefiner *topology_refiner)
147 {
148  const int num_faces = topology_refiner->getNumFaces(topology_refiner);
149  int num_ptex_faces = 0;
150  for (int face_index = 0; face_index < num_faces; ++face_index) {
151  num_ptex_faces += topology_refiner->getNumFacePtexFaces(topology_refiner, face_index);
152  }
153  return num_ptex_faces;
154 }
155 
156 void fillFacePtexIndexOffset(const OpenSubdiv_TopologyRefiner *topology_refiner,
157  int *face_ptex_index_offset)
158 {
159  const int num_faces = topology_refiner->getNumFaces(topology_refiner);
160  int num_ptex_faces = 0;
161  for (int face_index = 0; face_index < num_faces; ++face_index) {
162  face_ptex_index_offset[face_index] = num_ptex_faces;
163  num_ptex_faces += topology_refiner->getNumFacePtexFaces(topology_refiner, face_index);
164  }
165 }
166 
168 // Face-varying data.
169 
170 int getNumFVarChannels(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
171 {
172  const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner);
173  return base_level.GetNumFVarChannels();
174 }
175 
176 OpenSubdiv_FVarLinearInterpolation getFVarLinearInterpolation(
177  const struct OpenSubdiv_TopologyRefiner *topology_refiner)
178 {
180  getOSDTopologyRefiner(topology_refiner)->GetFVarLinearInterpolation());
181 }
182 
183 int getNumFVarValues(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int channel)
184 {
185  const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner);
186  return base_level.GetNumFVarValues(channel);
187 }
188 
189 const int *getFaceFVarValueIndices(const struct OpenSubdiv_TopologyRefiner *topology_refiner,
190  const int face_index,
191  const int channel)
192 {
193  const OpenSubdiv::Far::TopologyLevel &base_level = getOSDTopologyBaseLevel(topology_refiner);
194  return &base_level.GetFaceFVarValues(face_index, channel)[0];
195 }
196 
198 // Internal helpers.
199 
200 void assignFunctionPointers(OpenSubdiv_TopologyRefiner *topology_refiner)
201 {
202  topology_refiner->getSubdivisionLevel = getSubdivisionLevel;
203  topology_refiner->getIsAdaptive = getIsAdaptive;
204  // Basic topology information.
205  topology_refiner->getNumVertices = getNumVertices;
206  topology_refiner->getNumEdges = getNumEdges;
207  topology_refiner->getNumFaces = getNumFaces;
208  topology_refiner->getNumFaceVertices = getNumFaceVertices;
209  topology_refiner->getFaceVertices = getFaceVertices;
210  topology_refiner->getNumFaceEdges = getNumFaceEdges;
211  topology_refiner->getFaceEdges = getFaceEdges;
212  topology_refiner->getEdgeVertices = getEdgeVertices;
213  topology_refiner->getNumVertexEdges = getNumVertexEdges;
214  topology_refiner->getVertexEdges = getVertexEdges;
215  // PTex face geometry.
216  topology_refiner->getNumFacePtexFaces = getNumFacePtexFaces;
217  topology_refiner->getNumPtexFaces = getNumPtexFaces;
218  topology_refiner->fillFacePtexIndexOffset = fillFacePtexIndexOffset;
219  // Face-varying data.
220  topology_refiner->getNumFVarChannels = getNumFVarChannels;
221  topology_refiner->getFVarLinearInterpolation = getFVarLinearInterpolation;
222  topology_refiner->getNumFVarValues = getNumFVarValues;
223  topology_refiner->getFaceFVarValueIndices = getFaceFVarValueIndices;
224 }
225 
226 OpenSubdiv_TopologyRefiner *allocateTopologyRefiner()
227 {
228  OpenSubdiv_TopologyRefiner *topology_refiner = OBJECT_GUARDED_NEW(OpenSubdiv_TopologyRefiner);
229  assignFunctionPointers(topology_refiner);
230  return topology_refiner;
231 }
232 
233 } // namespace
234 
236  OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings *settings)
237 {
239 
240  TopologyRefinerImpl *topology_refiner_impl = TopologyRefinerImpl::createFromConverter(converter,
241  *settings);
242  if (topology_refiner_impl == nullptr) {
243  return nullptr;
244  }
245 
246  OpenSubdiv_TopologyRefiner *topology_refiner = allocateTopologyRefiner();
247  topology_refiner->impl = static_cast<OpenSubdiv_TopologyRefinerImpl *>(topology_refiner_impl);
248 
249  return topology_refiner;
250 }
251 
253 {
254  delete topology_refiner->impl;
255  OBJECT_GUARDED_DELETE(topology_refiner, OpenSubdiv_TopologyRefiner);
256 }
257 
259  const OpenSubdiv_TopologyRefiner *topology_refiner, const OpenSubdiv_Converter *converter)
260 {
261  return topology_refiner->impl->isEqualToConverter(converter);
262 }
Read Guarded memory(de)allocation.
virtual int getNumVertices() const
Definition: btBox2dShape.h:140
virtual int getNumEdges() const
Definition: btBox2dShape.h:174
size_t size() const
Definition: util_array.h:203
OpenSubdiv::Far::TopologyRefiner * topology_refiner
OpenSubdiv_TopologyRefinerSettings settings
bool isEqualToConverter(const OpenSubdiv_Converter *converter) const
OpenSubdiv_FVarLinearInterpolation getCAPIFVarLinearInterpolationFromOSD(OpenSubdiv::Sdc::Options::FVarLinearInterpolation linear_interpolation)
Definition: type_convert.cc:67
std::vector< ElementType, Eigen::aligned_allocator< ElementType > > vector
Definition: vector.h:39
OpenSubdiv_FVarLinearInterpolation
int(* getNumVertexEdges)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int vertex_index)
int(* getNumFaceVertices)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index)
void(* getFaceEdges)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index, int *face_edges_indices)
void(* fillFacePtexIndexOffset)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, int *face_ptex_index_offset)
void(* getFaceVertices)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index, int *face_vertices_indices)
int(* getNumPtexFaces)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
void(* getVertexEdges)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int vertex_index, int *vertex_edges_indices)
OpenSubdiv_FVarLinearInterpolation(* getFVarLinearInterpolation)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
struct OpenSubdiv_TopologyRefinerImpl * impl
int(* getNumFVarValues)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int channel)
void(* getEdgeVertices)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int edge_index, int edge_vertices_indices[2])
bool(* getIsAdaptive)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
const int *(* getFaceFVarValueIndices)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index, const int channel)
int(* getSubdivisionLevel)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
int(* getNumFaceEdges)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index)
int(* getNumFaces)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
int(* getNumFacePtexFaces)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index)
int(* getNumFVarChannels)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
int(* getNumEdges)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
int(* getNumVertices)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
void openSubdiv_deleteTopologyRefiner(OpenSubdiv_TopologyRefiner *topology_refiner)
bool openSubdiv_topologyRefinerCompareWithConverter(const OpenSubdiv_TopologyRefiner *topology_refiner, const OpenSubdiv_Converter *converter)
OpenSubdiv_TopologyRefiner * openSubdiv_createTopologyRefinerFromConverter(OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings *settings)