Blender  V3.3
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 = MEM_new<OpenSubdiv_TopologyRefiner>(__func__);
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  MEM_delete(topology_refiner);
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.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a vector
virtual int getNumVertices() const
Definition: btBox2dShape.h:140
virtual int getNumEdges() const
Definition: btBox2dShape.h:174
size_t size() const
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
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)