|
Blender
V2.59
|
00001 /* 00002 * $Id: BLI_pbvh.h 35215 2011-02-27 08:31:10Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * ***** END GPL LICENSE BLOCK ***** 00021 */ 00022 00023 #ifndef BLI_PBVH_H 00024 #define BLI_PBVH_H 00025 00031 struct MFace; 00032 struct MVert; 00033 struct DMGridAdjacency; 00034 struct DMGridData; 00035 struct PBVH; 00036 struct PBVHNode; 00037 struct ListBase; 00038 00039 typedef struct PBVH PBVH; 00040 typedef struct PBVHNode PBVHNode; 00041 00042 typedef struct { 00043 float (*co)[3]; 00044 } PBVHProxyNode; 00045 00046 /* Callbacks */ 00047 00048 /* returns 1 if the search should continue from this node, 0 otherwise */ 00049 typedef int (*BLI_pbvh_SearchCallback)(PBVHNode *node, void *data); 00050 00051 typedef void (*BLI_pbvh_HitCallback)(PBVHNode *node, void *data); 00052 typedef void (*BLI_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float* tmin); 00053 00054 /* Building */ 00055 00056 PBVH *BLI_pbvh_new(void); 00057 void BLI_pbvh_build_mesh(PBVH *bvh, struct MFace *faces, struct MVert *verts, 00058 int totface, int totvert); 00059 void BLI_pbvh_build_grids(PBVH *bvh, struct DMGridData **grids, 00060 struct DMGridAdjacency *gridadj, int totgrid, 00061 int gridsize, void **gridfaces); 00062 void BLI_pbvh_free(PBVH *bvh); 00063 00064 /* Hierarchical Search in the BVH, two methods: 00065 * for each hit calling a callback 00066 * gather nodes in an array (easy to multithread) */ 00067 00068 void BLI_pbvh_search_callback(PBVH *bvh, 00069 BLI_pbvh_SearchCallback scb, void *search_data, 00070 BLI_pbvh_HitCallback hcb, void *hit_data); 00071 00072 void BLI_pbvh_search_gather(PBVH *bvh, 00073 BLI_pbvh_SearchCallback scb, void *search_data, 00074 PBVHNode ***array, int *tot); 00075 00076 /* Raycast 00077 the hit callback is called for all leaf nodes intersecting the ray; 00078 it's up to the callback to find the primitive within the leaves that is 00079 hit first */ 00080 00081 void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data, 00082 float ray_start[3], float ray_normal[3], int original); 00083 int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], 00084 float ray_start[3], float ray_normal[3], float *dist); 00085 00086 /* Drawing */ 00087 00088 void BLI_pbvh_node_draw(PBVHNode *node, void *data); 00089 int BLI_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data); 00090 void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3], int smooth); 00091 00092 /* Node Access */ 00093 00094 typedef enum { 00095 PBVH_Leaf = 1, 00096 00097 PBVH_UpdateNormals = 2, 00098 PBVH_UpdateBB = 4, 00099 PBVH_UpdateOriginalBB = 8, 00100 PBVH_UpdateDrawBuffers = 16, 00101 PBVH_UpdateRedraw = 32 00102 } PBVHNodeFlags; 00103 00104 void BLI_pbvh_node_mark_update(PBVHNode *node); 00105 00106 void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, 00107 int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, 00108 struct DMGridData ***griddata, struct DMGridAdjacency **gridadj); 00109 void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, 00110 int *uniquevert, int *totvert); 00111 void BLI_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node, 00112 int **vert_indices, struct MVert **verts); 00113 00114 void BLI_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3]); 00115 void BLI_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max[3]); 00116 00117 float BLI_pbvh_node_get_tmin(PBVHNode* node); 00118 00119 /* Update Normals/Bounding Box/Draw Buffers/Redraw and clear flags */ 00120 00121 void BLI_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]); 00122 void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3]); 00123 void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface); 00124 void BLI_pbvh_grids_update(PBVH *bvh, struct DMGridData **grids, 00125 struct DMGridAdjacency *gridadj, void **gridfaces); 00126 00127 /* vertex deformer */ 00128 float (*BLI_pbvh_get_vertCos(struct PBVH *pbvh))[3]; 00129 void BLI_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]); 00130 int BLI_pbvh_isDeformed(struct PBVH *pbvh); 00131 00132 00133 /* Vertex Iterator */ 00134 00135 /* this iterator has quite a lot of code, but it's designed to: 00136 - allow the compiler to eliminate dead code and variables 00137 - spend most of the time in the relatively simple inner loop */ 00138 00139 #define PBVH_ITER_ALL 0 00140 #define PBVH_ITER_UNIQUE 1 00141 00142 typedef struct PBVHVertexIter { 00143 /* iteration */ 00144 int g; 00145 int width; 00146 int height; 00147 int skip; 00148 int gx; 00149 int gy; 00150 int i; 00151 00152 /* grid */ 00153 struct DMGridData **grids; 00154 struct DMGridData *grid; 00155 int *grid_indices; 00156 int totgrid; 00157 int gridsize; 00158 00159 /* mesh */ 00160 struct MVert *mverts; 00161 int totvert; 00162 int *vert_indices; 00163 00164 /* result: these are all computed in the macro, but we assume 00165 that compiler optimizations will skip the ones we don't use */ 00166 struct MVert *mvert; 00167 float *co; 00168 short *no; 00169 float *fno; 00170 } PBVHVertexIter; 00171 00172 #ifdef _MSC_VER 00173 #pragma warning (disable:4127) // conditional expression is constant 00174 #endif 00175 00176 #define BLI_pbvh_vertex_iter_begin(bvh, node, vi, mode) \ 00177 { \ 00178 struct DMGridData **grids; \ 00179 struct MVert *verts; \ 00180 int *grid_indices, totgrid, gridsize, *vert_indices, uniq_verts, totvert; \ 00181 \ 00182 vi.grid= 0; \ 00183 vi.no= 0; \ 00184 vi.fno= 0; \ 00185 vi.mvert= 0; \ 00186 vi.skip= 0; \ 00187 \ 00188 BLI_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids, NULL); \ 00189 BLI_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert); \ 00190 BLI_pbvh_node_get_verts(bvh, node, &vert_indices, &verts); \ 00191 \ 00192 vi.grids= grids; \ 00193 vi.grid_indices= grid_indices; \ 00194 vi.totgrid= (grids)? totgrid: 1; \ 00195 vi.gridsize= gridsize; \ 00196 \ 00197 if(mode == PBVH_ITER_ALL) \ 00198 vi.totvert = totvert; \ 00199 else \ 00200 vi.totvert= uniq_verts; \ 00201 vi.vert_indices= vert_indices; \ 00202 vi.mverts= verts; \ 00203 }\ 00204 \ 00205 for(vi.i=0, vi.g=0; vi.g<vi.totgrid; vi.g++) { \ 00206 if(vi.grids) { \ 00207 vi.width= vi.gridsize; \ 00208 vi.height= vi.gridsize; \ 00209 vi.grid= vi.grids[vi.grid_indices[vi.g]]; \ 00210 vi.skip= 0; \ 00211 \ 00212 /*if(mode == PVBH_ITER_UNIQUE) { \ 00213 vi.grid += subm->grid.offset; \ 00214 vi.skip= subm->grid.skip; \ 00215 vi.grid -= skip; \ 00216 }*/ \ 00217 } \ 00218 else { \ 00219 vi.width= vi.totvert; \ 00220 vi.height= 1; \ 00221 } \ 00222 \ 00223 for(vi.gy=0; vi.gy<vi.height; vi.gy++) { \ 00224 if(vi.grid) vi.grid += vi.skip; \ 00225 \ 00226 for(vi.gx=0; vi.gx<vi.width; vi.gx++, vi.i++) { \ 00227 if(vi.grid) { \ 00228 vi.co= vi.grid->co; \ 00229 vi.fno= vi.grid->no; \ 00230 vi.grid++; \ 00231 } \ 00232 else { \ 00233 vi.mvert= &vi.mverts[vi.vert_indices[vi.gx]]; \ 00234 vi.co= vi.mvert->co; \ 00235 vi.no= vi.mvert->no; \ 00236 } \ 00237 00238 #define BLI_pbvh_vertex_iter_end \ 00239 } \ 00240 } \ 00241 } 00242 00243 void BLI_pbvh_node_get_proxies(PBVHNode* node, PBVHProxyNode** proxies, int* proxy_count); 00244 void BLI_pbvh_node_free_proxies(PBVHNode* node); 00245 PBVHProxyNode* BLI_pbvh_node_add_proxy(PBVH* bvh, PBVHNode* node); 00246 void BLI_pbvh_gather_proxies(PBVH* pbvh, PBVHNode*** nodes, int* totnode); 00247 00248 //void BLI_pbvh_node_BB_reset(PBVHNode* node); 00249 //void BLI_pbvh_node_BB_expand(PBVHNode* node, float co[3]); 00250 00251 #endif /* BLI_PBVH_H */ 00252