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