1 // Copyright 2018 Blender Foundation. All rights reserved.
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.
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.
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.
17 // Author: Sergey Sharybin
19 #ifndef OPENSUBDIV_TOPOLOGY_REFINER_CAPI_H_
20 #define OPENSUBDIV_TOPOLOGY_REFINER_CAPI_H_
22 #include <stdint.h> // for bool
24 #include "opensubdiv_capi_type.h"
30 struct OpenSubdiv_Converter;
31 struct OpenSubdiv_TopologyRefinerInternal;
33 // Those settings don't really belong to OpenSubdiv's topology refiner, but
34 // we are keeping track of them on our side of topology refiner. This is to
35 // make it possible to ensure we are not trying to abuse same OpenSubdiv's
36 // topology refiner with different subdivision levels or with different
38 typedef struct OpenSubdiv_TopologyRefinerSettings {
41 } OpenSubdiv_TopologyRefinerSettings;
43 typedef struct OpenSubdiv_TopologyRefiner {
44 // Query subdivision level the refiner is created for.
45 int (*getSubdivisionLevel)(
46 const struct OpenSubdiv_TopologyRefiner* topology_refiner);
47 bool (*getIsAdaptive)(
48 const struct OpenSubdiv_TopologyRefiner* topology_refiner);
50 // NOTE: All queries are querying base level.
52 // TODO(sergey): Consider making it more obvious in function naming,
53 // but since it's unlikely (or at least, will be uncommon use) for API
54 // which queries final geometry, we should be fine with this name for
57 //////////////////////////////////////////////////////////////////////////////
58 // Query basic topology information from base level.
60 int (*getNumVertices)(
61 const struct OpenSubdiv_TopologyRefiner* topology_refiner);
63 const struct OpenSubdiv_TopologyRefiner* topology_refiner);
65 const struct OpenSubdiv_TopologyRefiner* topology_refiner);
66 int (*getNumFaceVertices)(
67 const struct OpenSubdiv_TopologyRefiner* topology_refiner,
68 const int face_index);
69 void (*getFaceVertices)(
70 const struct OpenSubdiv_TopologyRefiner* topology_refiner,
72 int* face_vertices_indices);
73 int (*getNumFaceEdges)(
74 const struct OpenSubdiv_TopologyRefiner* topology_refiner,
75 const int face_index);
77 const struct OpenSubdiv_TopologyRefiner* topology_refiner,
79 int* face_edges_indices);
80 void (*getEdgeVertices)(
81 const struct OpenSubdiv_TopologyRefiner* topology_refiner,
83 int edge_vertices_indices[2]);
85 //////////////////////////////////////////////////////////////////////////////
86 // PTex face geometry queries.
88 // Ptex face corresponds to OpenSubdiv's internal "patch" and to Blender's
89 // subdivision grid. The rule commes as:
90 // - Triangle face consist of 3 ptex faces, ordered in the order of
92 // - Quad face consists of a single ptex face.
93 // - N-gons (similar to triangle) consists of N ptex faces, ordered same
94 // way as for triangle.
95 int (*getNumFacePtexFaces)(
96 const struct OpenSubdiv_TopologyRefiner* topology_refiner,
97 const int face_index);
98 int (*getNumPtexFaces)(
99 const struct OpenSubdiv_TopologyRefiner* topology_refiner);
101 // Initialize a per-base-face offset measured in ptex face indices.
103 // Basically, face_ptex_offset[base_face_index] is a total number of ptex
104 // faces created for bases faces [0 .. base_face_index - 1].
106 // The array must contain at least total number of ptex faces elements.
107 void (*fillFacePtexIndexOffset)(
108 const struct OpenSubdiv_TopologyRefiner* topology_refiner,
109 int* face_ptex_index_offset);
111 //////////////////////////////////////////////////////////////////////////////
112 // Face-varying data.
114 // Number of face-varying channels (or how they are called in Blender layers).
115 int (*getNumFVarChannels)(
116 const struct OpenSubdiv_TopologyRefiner* topology_refiner);
117 // Get face-varying interpolation type.
118 OpenSubdiv_FVarLinearInterpolation (*getFVarLinearInterpolation)(
119 const struct OpenSubdiv_TopologyRefiner* topology_refiner);
120 // Get total number of face-varying values in a particular channel.
121 int (*getNumFVarValues)(
122 const struct OpenSubdiv_TopologyRefiner* topology_refiner,
124 // Get face-varying value indices associated with a particular face.
126 // This is an array of indices inside of face-varying array, array elements
127 // are aligned with face corners (or loops in Blender terminology).
128 const int* (*getFaceFVarValueIndices)(
129 const struct OpenSubdiv_TopologyRefiner* topology_refiner,
130 const int face_index,
133 //////////////////////////////////////////////////////////////////////////////
136 // Internal storage for the use in this module only.
138 // Tease: Contains actual OpenSubdiv's refiner and (optionally) some other
139 // data and state needed for an internbal use.
140 struct OpenSubdiv_TopologyRefinerInternal* internal;
141 } OpenSubdiv_TopologyRefiner;
143 // NOTE: Will return NULL in cases of bad topology.
144 // NOTE: Mesh without faces is considered a bad topology.
145 OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter(
146 struct OpenSubdiv_Converter* converter,
147 const OpenSubdiv_TopologyRefinerSettings* settings);
149 void openSubdiv_deleteTopologyRefiner(
150 OpenSubdiv_TopologyRefiner* topology_refiner);
152 // Compare given topology refiner with converter. Returns truth if topology
153 // refiner matches given converter, false otherwise.
155 // This allows users to construct converter (which is supposed to be cheap)
156 // and compare with existing refiner before going into more computationally
157 // complicated parts of subdivision process.
158 bool openSubdiv_topologyRefinerCompareWithConverter(
159 const OpenSubdiv_TopologyRefiner* topology_refiner,
160 const struct OpenSubdiv_Converter* converter);
166 #endif // OPENSUBDIV_TOPOLOGY_REFINER_CAPI_H_