1 /* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License 4 * as published by the Free Software Foundation; either version 2 5 * of the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software Foundation, 14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 * 16 * The Original Code is Copyright (C) 2018 by Blender Foundation. 17 * All rights reserved. 18 */ 19 20 /** \file 21 * \ingroup bke 22 */ 23 24 #pragma once 25 26 #include "BLI_sys_types.h" 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 struct Mesh; 33 struct Subdiv; 34 struct SubdivForeachContext; 35 struct SubdivToMeshSettings; 36 37 typedef bool (*SubdivForeachTopologyInformationCb)(const struct SubdivForeachContext *context, 38 const int num_vertices, 39 const int num_edges, 40 const int num_loops, 41 const int num_polygons); 42 43 typedef void (*SubdivForeachVertexFromCornerCb)(const struct SubdivForeachContext *context, 44 void *tls, 45 const int ptex_face_index, 46 const float u, 47 const float v, 48 const int coarse_vertex_index, 49 const int coarse_poly_index, 50 const int coarse_corner, 51 const int subdiv_vertex_index); 52 53 typedef void (*SubdivForeachVertexFromEdgeCb)(const struct SubdivForeachContext *context, 54 void *tls, 55 const int ptex_face_index, 56 const float u, 57 const float v, 58 const int coarse_edge_index, 59 const int coarse_poly_index, 60 const int coarse_corner, 61 const int subdiv_vertex_index); 62 63 typedef void (*SubdivForeachVertexInnerCb)(const struct SubdivForeachContext *context, 64 void *tls, 65 const int ptex_face_index, 66 const float u, 67 const float v, 68 const int coarse_poly_index, 69 const int coarse_corner, 70 const int subdiv_vertex_index); 71 72 typedef void (*SubdivForeachEdgeCb)(const struct SubdivForeachContext *context, 73 void *tls, 74 const int coarse_edge_index, 75 const int subdiv_edge_index, 76 const int subdiv_v1, 77 const int subdiv_v2); 78 79 typedef void (*SubdivForeachLoopCb)(const struct SubdivForeachContext *context, 80 void *tls, 81 const int ptex_face_index, 82 const float u, 83 const float v, 84 const int coarse_loop_index, 85 const int coarse_poly_index, 86 const int coarse_corner, 87 const int subdiv_loop_index, 88 const int subdiv_vertex_index, 89 const int subdiv_edge_index); 90 91 typedef void (*SubdivForeachPolygonCb)(const struct SubdivForeachContext *context, 92 void *tls, 93 const int coarse_poly_index, 94 const int subdiv_poly_index, 95 const int start_loop_index, 96 const int num_loops); 97 98 typedef void (*SubdivForeachLooseCb)(const struct SubdivForeachContext *context, 99 void *tls, 100 const int coarse_vertex_index, 101 const int subdiv_vertex_index); 102 103 typedef void (*SubdivForeachVertexOfLooseEdgeCb)(const struct SubdivForeachContext *context, 104 void *tls, 105 const int coarse_edge_index, 106 const float u, 107 const int subdiv_vertex_index); 108 109 typedef struct SubdivForeachContext { 110 /* Is called when topology information becomes available. 111 * Is only called once. 112 * 113 * NOTE: If this callback returns false, the foreach loop is aborted. 114 */ 115 SubdivForeachTopologyInformationCb topology_info; 116 /* These callbacks are called from every ptex which shares "emitting" 117 * vertex or edge. 118 */ 119 SubdivForeachVertexFromCornerCb vertex_every_corner; 120 SubdivForeachVertexFromEdgeCb vertex_every_edge; 121 /* Those callbacks are run once per subdivision vertex, ptex is undefined 122 * as in it will be whatever first ptex face happened to be traversed in 123 * the multi-threaded environment and which shares "emitting" vertex or 124 * edge. 125 */ 126 SubdivForeachVertexFromCornerCb vertex_corner; 127 SubdivForeachVertexFromEdgeCb vertex_edge; 128 /* Called exactly once, always corresponds to a single ptex face. */ 129 SubdivForeachVertexInnerCb vertex_inner; 130 /* Called once for each loose vertex. One loose coarse vertexcorresponds 131 * to a single subdivision vertex. 132 */ 133 SubdivForeachLooseCb vertex_loose; 134 /* Called once per vertex created for loose edge. */ 135 SubdivForeachVertexOfLooseEdgeCb vertex_of_loose_edge; 136 /* NOTE: If subdivided edge does not come from coarse edge, ORIGINDEX_NONE 137 * will be passed as coarse_edge_index. 138 */ 139 SubdivForeachEdgeCb edge; 140 /* NOTE: If subdivided loop does not come from coarse loop, ORIGINDEX_NONE 141 * will be passed as coarse_loop_index. 142 */ 143 SubdivForeachLoopCb loop; 144 SubdivForeachPolygonCb poly; 145 146 /* User-defined pointer, to allow callbacks know something about context the 147 * traversal is happening for, 148 */ 149 void *user_data; 150 151 /* Initial value of TLS data. */ 152 void *user_data_tls; 153 /* Size of TLS data. */ 154 size_t user_data_tls_size; 155 /* Function to free TLS storage. */ 156 void (*user_data_tls_free)(void *tls); 157 } SubdivForeachContext; 158 159 /* Invokes callbacks in the order and with values which corresponds to creation 160 * of final subdivided mesh. 161 * 162 * Main goal is to abstract all the traversal routines to give geometry element 163 * indices (for vertices, edges, loops, polygons) in the same way as subdivision 164 * modifier will do for a dense mesh. 165 * 166 * Returns truth if the whole topology was traversed, without any early exits. 167 * 168 * TODO(sergey): Need to either get rid of subdiv or of coarse_mesh. 169 * The main point here is to be able to get base level topology, which can be 170 * done with either of those. Having both of them is kind of redundant. 171 */ 172 bool BKE_subdiv_foreach_subdiv_geometry(struct Subdiv *subdiv, 173 const struct SubdivForeachContext *context, 174 const struct SubdivToMeshSettings *mesh_settings, 175 const struct Mesh *coarse_mesh); 176 177 #ifdef __cplusplus 178 } 179 #endif 180