Blender  V2.59
pbvh.c
Go to the documentation of this file.
00001 /*
00002  * $Id: pbvh.c 38867 2011-07-31 02:34:53Z nicholasbishop $
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 
00029 #include "DNA_meshdata_types.h"
00030 
00031 #include "MEM_guardedalloc.h"
00032 
00033 #include "BLI_math.h"
00034 #include "BLI_utildefines.h"
00035 #include "BLI_ghash.h"
00036 #include "BLI_pbvh.h"
00037 
00038 #include "BKE_DerivedMesh.h"
00039 #include "BKE_mesh.h" /* for mesh_calc_normals */
00040 #include "BKE_global.h" /* for mesh_calc_normals */
00041 
00042 #include "GPU_buffers.h"
00043 
00044 #define LEAF_LIMIT 10000
00045 
00046 //#define PERFCNTRS
00047 
00048 /* Bitmap */
00049 typedef char* BLI_bitmap;
00050 
00051 static BLI_bitmap BLI_bitmap_new(int tot)
00052 {
00053         return MEM_callocN((tot >> 3) + 1, "BLI bitmap");
00054 }
00055 
00056 static int BLI_bitmap_get(BLI_bitmap b, int index)
00057 {
00058         return b[index >> 3] & (1 << (index & 7));
00059 }
00060 
00061 static void BLI_bitmap_set(BLI_bitmap b, int index)
00062 {
00063         b[index >> 3] |= (1 << (index & 7));
00064 }
00065 
00066 #if 0 /* UNUSED */
00067 static void BLI_bitmap_clear(BLI_bitmap b, int index)
00068 {
00069         b[index >> 3] &= ~(1 << (index & 7));
00070 }
00071 #endif
00072 
00073 /* Axis-aligned bounding box */
00074 typedef struct {
00075         float bmin[3], bmax[3];
00076 } BB;
00077 
00078 /* Axis-aligned bounding box with centroid */
00079 typedef struct {
00080         float bmin[3], bmax[3], bcentroid[3];
00081 } BBC;
00082 
00083 struct PBVHNode {
00084         /* Opaque handle for drawing code */
00085         void *draw_buffers;
00086 
00087         /* Voxel bounds */
00088         BB vb;
00089         BB orig_vb;
00090 
00091         /* For internal nodes, the offset of the children in the PBVH
00092            'nodes' array. */
00093         int children_offset;
00094 
00095         /* Pointer into the PBVH prim_indices array and the number of
00096            primitives used by this leaf node.
00097 
00098            Used for leaf nodes in both mesh- and multires-based PBVHs.
00099         */
00100         int *prim_indices;
00101         unsigned int totprim;
00102 
00103         /* Array of indices into the mesh's MVert array. Contains the
00104            indices of all vertices used by faces that are within this
00105            node's bounding box.
00106 
00107            Note that a vertex might be used by a multiple faces, and
00108            these faces might be in different leaf nodes. Such a vertex
00109            will appear in the vert_indices array of each of those leaf
00110            nodes.
00111 
00112            In order to support cases where you want access to multiple
00113            nodes' vertices without duplication, the vert_indices array
00114            is ordered such that the first part of the array, up to
00115            index 'uniq_verts', contains "unique" vertex indices. These
00116            vertices might not be truly unique to this node, but if
00117            they appear in another node's vert_indices array, they will
00118            be above that node's 'uniq_verts' value.
00119 
00120            Used for leaf nodes in a mesh-based PBVH (not multires.)
00121         */
00122         int *vert_indices;
00123         unsigned int uniq_verts, face_verts;
00124 
00125         /* An array mapping face corners into the vert_indices
00126            array. The array is sized to match 'totprim', and each of
00127            the face's corners gets an index into the vert_indices
00128            array, in the same order as the corners in the original
00129            MFace. The fourth value should not be used if the original
00130            face is a triangle.
00131 
00132            Used for leaf nodes in a mesh-based PBVH (not multires.)
00133         */
00134         int (*face_vert_indices)[4];
00135 
00136         /* Indicates whether this node is a leaf or not; also used for
00137            marking various updates that need to be applied. */
00138         PBVHNodeFlags flag : 8;
00139 
00140         /* Used for raycasting: how close bb is to the ray point. */
00141         float tmin;
00142 
00143         int proxy_count;
00144         PBVHProxyNode* proxies;
00145 };
00146 
00147 struct PBVH {
00148         PBVHNode *nodes;
00149         int node_mem_count, totnode;
00150 
00151         int *prim_indices;
00152         int totprim;
00153         int totvert;
00154 
00155         int leaf_limit;
00156 
00157         /* Mesh data */
00158         MVert *verts;
00159         MFace *faces;
00160 
00161         /* Grid Data */
00162         DMGridData **grids;
00163         DMGridAdjacency *gridadj;
00164         void **gridfaces;
00165         int totgrid;
00166         int gridsize;
00167 
00168         /* Only used during BVH build and update,
00169            don't need to remain valid after */
00170         BLI_bitmap vert_bitmap;
00171 
00172 #ifdef PERFCNTRS
00173         int perf_modified;
00174 #endif
00175 
00176         /* flag are verts/faces deformed */
00177         int deformed;
00178 };
00179 
00180 #define STACK_FIXED_DEPTH       100
00181 
00182 typedef struct PBVHStack {
00183         PBVHNode *node;
00184         int revisiting;
00185 } PBVHStack;
00186 
00187 typedef struct PBVHIter {
00188         PBVH *bvh;
00189         BLI_pbvh_SearchCallback scb;
00190         void *search_data;
00191 
00192         PBVHStack *stack;
00193         int stacksize;
00194 
00195         PBVHStack stackfixed[STACK_FIXED_DEPTH];
00196         int stackspace;
00197 } PBVHIter;
00198 
00199 static void BB_reset(BB *bb)
00200 {
00201         bb->bmin[0] = bb->bmin[1] = bb->bmin[2] = FLT_MAX;
00202         bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
00203 }
00204 
00205 /* Expand the bounding box to include a new coordinate */
00206 static void BB_expand(BB *bb, float co[3])
00207 {
00208         int i;
00209         for(i = 0; i < 3; ++i) {
00210                 bb->bmin[i] = MIN2(bb->bmin[i], co[i]);
00211                 bb->bmax[i] = MAX2(bb->bmax[i], co[i]);
00212         }
00213 }
00214 
00215 /* Expand the bounding box to include another bounding box */
00216 static void BB_expand_with_bb(BB *bb, BB *bb2)
00217 {
00218         int i;
00219         for(i = 0; i < 3; ++i) {
00220                 bb->bmin[i] = MIN2(bb->bmin[i], bb2->bmin[i]);
00221                 bb->bmax[i] = MAX2(bb->bmax[i], bb2->bmax[i]);
00222         }
00223 }
00224 
00225 /* Return 0, 1, or 2 to indicate the widest axis of the bounding box */
00226 static int BB_widest_axis(BB *bb)
00227 {
00228         float dim[3];
00229         int i;
00230 
00231         for(i = 0; i < 3; ++i)
00232                 dim[i] = bb->bmax[i] - bb->bmin[i];
00233 
00234         if(dim[0] > dim[1]) {
00235                 if(dim[0] > dim[2])
00236                         return 0;
00237                 else
00238                         return 2;
00239         }
00240         else {
00241                 if(dim[1] > dim[2])
00242                         return 1;
00243                 else
00244                         return 2;
00245         }
00246 }
00247 
00248 static void BBC_update_centroid(BBC *bbc)
00249 {
00250         int i;
00251         for(i = 0; i < 3; ++i)
00252                 bbc->bcentroid[i] = (bbc->bmin[i] + bbc->bmax[i]) * 0.5f;
00253 }
00254 
00255 /* Not recursive */
00256 static void update_node_vb(PBVH *bvh, PBVHNode *node)
00257 {
00258         BB vb;
00259 
00260         BB_reset(&vb);
00261         
00262         if(node->flag & PBVH_Leaf) {
00263                 PBVHVertexIter vd;
00264 
00265                 BLI_pbvh_vertex_iter_begin(bvh, node, vd, PBVH_ITER_ALL) {
00266                         BB_expand(&vb, vd.co);
00267                 }
00268                 BLI_pbvh_vertex_iter_end;
00269         }
00270         else {
00271                 BB_expand_with_bb(&vb,
00272                                   &bvh->nodes[node->children_offset].vb);
00273                 BB_expand_with_bb(&vb,
00274                                   &bvh->nodes[node->children_offset + 1].vb);
00275         }
00276 
00277         node->vb= vb;
00278 }
00279 
00280 //void BLI_pbvh_node_BB_reset(PBVHNode* node)
00281 //{
00282 //      BB_reset(&node->vb);
00283 //}
00284 //
00285 //void BLI_pbvh_node_BB_expand(PBVHNode* node, float co[3])
00286 //{
00287 //      BB_expand(&node->vb, co);
00288 //}
00289 
00290 
00291 /* Adapted from BLI_kdopbvh.c */
00292 /* Returns the index of the first element on the right of the partition */
00293 static int partition_indices(int *prim_indices, int lo, int hi, int axis,
00294                                  float mid, BBC *prim_bbc)
00295 {
00296         int i=lo, j=hi;
00297         for(;;) {
00298                 for(; prim_bbc[prim_indices[i]].bcentroid[axis] < mid; i++);
00299                 for(; mid < prim_bbc[prim_indices[j]].bcentroid[axis]; j--);
00300                 
00301                 if(!(i < j))
00302                         return i;
00303                 
00304                 SWAP(int, prim_indices[i], prim_indices[j]);
00305                 i++;
00306         }
00307 }
00308 
00309 static void check_partitioning(int *prim_indices, int lo, int hi, int axis,
00310                                    float mid, BBC *prim_bbc, int index_of_2nd_partition)
00311 {
00312         int i;
00313         for(i = lo; i <= hi; ++i) {
00314                 const float c = prim_bbc[prim_indices[i]].bcentroid[axis];
00315 
00316                 if((i < index_of_2nd_partition && c > mid) ||
00317                    (i > index_of_2nd_partition && c < mid)) {
00318                         printf("fail\n");
00319                 }
00320         }
00321 }
00322 
00323 static void grow_nodes(PBVH *bvh, int totnode)
00324 {
00325         if(totnode > bvh->node_mem_count) {
00326                 PBVHNode *prev = bvh->nodes;
00327                 bvh->node_mem_count *= 1.33;
00328                 if(bvh->node_mem_count < totnode)
00329                         bvh->node_mem_count = totnode;
00330                 bvh->nodes = MEM_callocN(sizeof(PBVHNode) * bvh->node_mem_count,
00331                                          "bvh nodes");
00332                 memcpy(bvh->nodes, prev, bvh->totnode * sizeof(PBVHNode));
00333                 MEM_freeN(prev);
00334         }
00335 
00336         bvh->totnode = totnode;
00337 }
00338 
00339 /* Add a vertex to the map, with a positive value for unique vertices and
00340    a negative value for additional vertices */
00341 static int map_insert_vert(PBVH *bvh, GHash *map,
00342                                 unsigned int *face_verts,
00343                                 unsigned int *uniq_verts, int vertex)
00344 {
00345         void *value, *key = SET_INT_IN_POINTER(vertex);
00346 
00347         if(!BLI_ghash_haskey(map, key)) {
00348                 if(BLI_bitmap_get(bvh->vert_bitmap, vertex)) {
00349                         value = SET_INT_IN_POINTER(-(*face_verts) - 1);
00350                         ++(*face_verts);
00351                 }
00352                 else {
00353                         BLI_bitmap_set(bvh->vert_bitmap, vertex);
00354                         value = SET_INT_IN_POINTER(*uniq_verts);
00355                         ++(*uniq_verts);
00356                 }
00357                 
00358                 BLI_ghash_insert(map, key, value);
00359                 return GET_INT_FROM_POINTER(value);
00360         }
00361         else
00362                 return GET_INT_FROM_POINTER(BLI_ghash_lookup(map, key));
00363 }
00364 
00365 /* Find vertices used by the faces in this node and update the draw buffers */
00366 static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
00367 {
00368         GHashIterator *iter;
00369         GHash *map;
00370         int i, j, totface;
00371 
00372         map = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "build_mesh_leaf_node gh");
00373         
00374         node->uniq_verts = node->face_verts = 0;
00375         totface= node->totprim;
00376 
00377         node->face_vert_indices = MEM_callocN(sizeof(int) * 4*totface,
00378                                               "bvh node face vert indices");
00379 
00380         for(i = 0; i < totface; ++i) {
00381                 MFace *f = bvh->faces + node->prim_indices[i];
00382                 int sides = f->v4 ? 4 : 3;
00383 
00384                 for(j = 0; j < sides; ++j) {
00385                         node->face_vert_indices[i][j]= 
00386                                 map_insert_vert(bvh, map, &node->face_verts,
00387                                                 &node->uniq_verts, (&f->v1)[j]);
00388                 }
00389         }
00390 
00391         node->vert_indices = MEM_callocN(sizeof(int) *
00392                                          (node->uniq_verts + node->face_verts),
00393                                          "bvh node vert indices");
00394 
00395         /* Build the vertex list, unique verts first */
00396         for(iter = BLI_ghashIterator_new(map), i = 0;
00397                 !BLI_ghashIterator_isDone(iter);
00398                 BLI_ghashIterator_step(iter), ++i) {
00399                 void *value = BLI_ghashIterator_getValue(iter);
00400                 int ndx = GET_INT_FROM_POINTER(value);
00401 
00402                 if(ndx < 0)
00403                         ndx = -ndx + node->uniq_verts - 1;
00404 
00405                 node->vert_indices[ndx] =
00406                         GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(iter));
00407         }
00408 
00409         BLI_ghashIterator_free(iter);
00410 
00411         for(i = 0; i < totface; ++i) {
00412                 MFace *f = bvh->faces + node->prim_indices[i];
00413                 int sides = f->v4 ? 4 : 3;
00414                 
00415                 for(j = 0; j < sides; ++j) {
00416                         if(node->face_vert_indices[i][j] < 0)
00417                                 node->face_vert_indices[i][j]=
00418                                         -node->face_vert_indices[i][j] +
00419                                         node->uniq_verts - 1;
00420                 }
00421         }
00422 
00423         if(!G.background) {
00424                 node->draw_buffers =
00425                         GPU_build_mesh_buffers(map, bvh->verts, bvh->faces,
00426                                         node->prim_indices,
00427                                         node->totprim, node->vert_indices,
00428                                         node->uniq_verts,
00429                                         node->uniq_verts + node->face_verts);
00430         }
00431 
00432         node->flag |= PBVH_UpdateDrawBuffers;
00433 
00434         BLI_ghash_free(map, NULL, NULL);
00435 }
00436 
00437 static void build_grids_leaf_node(PBVH *bvh, PBVHNode *node)
00438 {
00439         if(!G.background) {
00440                 node->draw_buffers =
00441                         GPU_build_grid_buffers(bvh->grids, node->prim_indices,
00442                                 node->totprim, bvh->gridsize);
00443         }
00444         node->flag |= PBVH_UpdateDrawBuffers;
00445 }
00446 
00447 /* Recursively build a node in the tree
00448 
00449    vb is the voxel box around all of the primitives contained in
00450    this node.
00451 
00452    cb is the bounding box around all the centroids of the primitives
00453    contained in this node
00454 
00455    offset and start indicate a range in the array of primitive indices
00456 */
00457 
00458 static void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
00459                    int offset, int count)
00460 {
00461         int i, axis, end;
00462         BB cb_backing;
00463 
00464         /* Decide whether this is a leaf or not */
00465         // XXX adapt leaf limit for grids
00466         if(count <= bvh->leaf_limit) {
00467                 bvh->nodes[node_index].flag |= PBVH_Leaf;
00468 
00469                 bvh->nodes[node_index].prim_indices = bvh->prim_indices + offset;
00470                 bvh->nodes[node_index].totprim = count;
00471 
00472                 /* Still need vb for searches */
00473                 BB_reset(&bvh->nodes[node_index].vb);
00474                 for(i = offset + count - 1; i >= offset; --i) {
00475                         BB_expand_with_bb(&bvh->nodes[node_index].vb,
00476                                           (BB*)(prim_bbc +
00477                                                 bvh->prim_indices[i]));
00478                 }
00479                 
00480                 if(bvh->faces)
00481                         build_mesh_leaf_node(bvh, bvh->nodes + node_index);
00482                 else
00483                         build_grids_leaf_node(bvh, bvh->nodes + node_index);
00484                 bvh->nodes[node_index].orig_vb= bvh->nodes[node_index].vb;
00485 
00486                 /* Done with this subtree */
00487                 return;
00488         }
00489         else {
00490                 BB_reset(&bvh->nodes[node_index].vb);
00491                 bvh->nodes[node_index].children_offset = bvh->totnode;
00492                 grow_nodes(bvh, bvh->totnode + 2);
00493 
00494                 if(!cb) {
00495                         cb = &cb_backing;
00496                         BB_reset(cb);
00497                         for(i = offset + count - 1; i >= offset; --i)
00498                                 BB_expand(cb, prim_bbc[bvh->prim_indices[i]].bcentroid);
00499                 }
00500         }
00501 
00502         axis = BB_widest_axis(cb);
00503 
00504         for(i = offset + count - 1; i >= offset; --i) {
00505                 BB_expand_with_bb(&bvh->nodes[node_index].vb,
00506                                   (BB*)(prim_bbc + bvh->prim_indices[i]));
00507         }
00508 
00509         bvh->nodes[node_index].orig_vb= bvh->nodes[node_index].vb;
00510 
00511         end = partition_indices(bvh->prim_indices, offset, offset + count - 1,
00512                                 axis,
00513                                 (cb->bmax[axis] + cb->bmin[axis]) * 0.5f,
00514                                 prim_bbc);
00515         check_partitioning(bvh->prim_indices, offset, offset + count - 1,
00516                            axis,
00517                            (cb->bmax[axis] + cb->bmin[axis]) * 0.5f,
00518                            prim_bbc, end);
00519 
00520         build_sub(bvh, bvh->nodes[node_index].children_offset, NULL,
00521                   prim_bbc, offset, end - offset);
00522         build_sub(bvh, bvh->nodes[node_index].children_offset + 1, NULL,
00523                   prim_bbc, end, offset + count - end);
00524 }
00525 
00526 static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim)
00527 {
00528         int i;
00529 
00530         if(totprim != bvh->totprim) {
00531                 bvh->totprim = totprim;
00532                 if(bvh->nodes) MEM_freeN(bvh->nodes);
00533                 if(bvh->prim_indices) MEM_freeN(bvh->prim_indices);
00534                 bvh->prim_indices = MEM_callocN(sizeof(int) * totprim,
00535                                                 "bvh prim indices");
00536                 for(i = 0; i < totprim; ++i)
00537                         bvh->prim_indices[i] = i;
00538                 bvh->totnode = 0;
00539                 if(bvh->node_mem_count < 100) {
00540                         bvh->node_mem_count = 100;
00541                         bvh->nodes = MEM_callocN(sizeof(PBVHNode) *
00542                                                  bvh->node_mem_count,
00543                                                  "bvh initial nodes");
00544                 }
00545         }
00546 
00547         bvh->totnode = 1;
00548         build_sub(bvh, 0, cb, prim_bbc, 0, totprim);
00549 }
00550 
00551 /* Do a full rebuild with on Mesh data structure */
00552 void BLI_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int totvert)
00553 {
00554         BBC *prim_bbc = NULL;
00555         BB cb;
00556         int i, j;
00557 
00558         bvh->faces = faces;
00559         bvh->verts = verts;
00560         bvh->vert_bitmap = BLI_bitmap_new(totvert);
00561         bvh->totvert = totvert;
00562         bvh->leaf_limit = LEAF_LIMIT;
00563 
00564         BB_reset(&cb);
00565 
00566         /* For each face, store the AABB and the AABB centroid */
00567         prim_bbc = MEM_mallocN(sizeof(BBC) * totface, "prim_bbc");
00568 
00569         for(i = 0; i < totface; ++i) {
00570                 MFace *f = faces + i;
00571                 const int sides = f->v4 ? 4 : 3;
00572                 BBC *bbc = prim_bbc + i;
00573 
00574                 BB_reset((BB*)bbc);
00575 
00576                 for(j = 0; j < sides; ++j)
00577                         BB_expand((BB*)bbc, verts[(&f->v1)[j]].co);
00578 
00579                 BBC_update_centroid(bbc);
00580 
00581                 BB_expand(&cb, bbc->bcentroid);
00582         }
00583 
00584         if(totface)
00585                 pbvh_build(bvh, &cb, prim_bbc, totface);
00586 
00587         MEM_freeN(prim_bbc);
00588         MEM_freeN(bvh->vert_bitmap);
00589 }
00590 
00591 /* Do a full rebuild with on Grids data structure */
00592 void BLI_pbvh_build_grids(PBVH *bvh, DMGridData **grids, DMGridAdjacency *gridadj,
00593         int totgrid, int gridsize, void **gridfaces)
00594 {
00595         BBC *prim_bbc = NULL;
00596         BB cb;
00597         int i, j;
00598 
00599         bvh->grids= grids;
00600         bvh->gridadj= gridadj;
00601         bvh->gridfaces= gridfaces;
00602         bvh->totgrid= totgrid;
00603         bvh->gridsize= gridsize;
00604         bvh->leaf_limit = MAX2(LEAF_LIMIT/((gridsize-1)*(gridsize-1)), 1);
00605 
00606         BB_reset(&cb);
00607 
00608         /* For each grid, store the AABB and the AABB centroid */
00609         prim_bbc = MEM_mallocN(sizeof(BBC) * totgrid, "prim_bbc");
00610 
00611         for(i = 0; i < totgrid; ++i) {
00612                 DMGridData *grid= grids[i];
00613                 BBC *bbc = prim_bbc + i;
00614 
00615                 BB_reset((BB*)bbc);
00616 
00617                 for(j = 0; j < gridsize*gridsize; ++j)
00618                         BB_expand((BB*)bbc, grid[j].co);
00619 
00620                 BBC_update_centroid(bbc);
00621 
00622                 BB_expand(&cb, bbc->bcentroid);
00623         }
00624 
00625         if(totgrid)
00626                 pbvh_build(bvh, &cb, prim_bbc, totgrid);
00627 
00628         MEM_freeN(prim_bbc);
00629 }
00630 
00631 PBVH *BLI_pbvh_new(void)
00632 {
00633         PBVH *bvh = MEM_callocN(sizeof(PBVH), "pbvh");
00634 
00635         return bvh;
00636 }
00637 
00638 void BLI_pbvh_free(PBVH *bvh)
00639 {
00640         PBVHNode *node;
00641         int i;
00642 
00643         for(i = 0; i < bvh->totnode; ++i) {
00644                 node= &bvh->nodes[i];
00645 
00646                 if(node->flag & PBVH_Leaf) {
00647                         if(node->draw_buffers)
00648                                 GPU_free_buffers(node->draw_buffers);
00649                         if(node->vert_indices)
00650                                 MEM_freeN(node->vert_indices);
00651                         if(node->face_vert_indices)
00652                                 MEM_freeN(node->face_vert_indices);
00653                 }
00654         }
00655 
00656         if (bvh->deformed) {
00657                 if (bvh->verts) {
00658                         /* if pbvh was deformed, new memory was allocated for verts/faces -- free it */
00659 
00660                         MEM_freeN(bvh->verts);
00661                         MEM_freeN(bvh->faces);
00662                 }
00663         }
00664 
00665         MEM_freeN(bvh->nodes);
00666         MEM_freeN(bvh->prim_indices);
00667         MEM_freeN(bvh);
00668 }
00669 
00670 static void pbvh_iter_begin(PBVHIter *iter, PBVH *bvh, BLI_pbvh_SearchCallback scb, void *search_data)
00671 {
00672         iter->bvh= bvh;
00673         iter->scb= scb;
00674         iter->search_data= search_data;
00675 
00676         iter->stack= iter->stackfixed;
00677         iter->stackspace= STACK_FIXED_DEPTH;
00678 
00679         iter->stack[0].node= bvh->nodes;
00680         iter->stack[0].revisiting= 0;
00681         iter->stacksize= 1;
00682 }
00683 
00684 static void pbvh_iter_end(PBVHIter *iter)
00685 {
00686         if(iter->stackspace > STACK_FIXED_DEPTH)
00687                 MEM_freeN(iter->stack);
00688 }
00689 
00690 static void pbvh_stack_push(PBVHIter *iter, PBVHNode *node, int revisiting)
00691 {
00692         if(iter->stacksize == iter->stackspace) {
00693                 PBVHStack *newstack;
00694 
00695                 iter->stackspace *= 2;
00696                 newstack= MEM_callocN(sizeof(PBVHStack)*iter->stackspace, "PBVHStack");
00697                 memcpy(newstack, iter->stack, sizeof(PBVHStack)*iter->stacksize);
00698 
00699                 if(iter->stackspace > STACK_FIXED_DEPTH)
00700                         MEM_freeN(iter->stack);
00701                 iter->stack= newstack;
00702         }
00703 
00704         iter->stack[iter->stacksize].node= node;
00705         iter->stack[iter->stacksize].revisiting= revisiting;
00706         iter->stacksize++;
00707 }
00708 
00709 static PBVHNode *pbvh_iter_next(PBVHIter *iter)
00710 {
00711         PBVHNode *node;
00712         int revisiting;
00713 
00714         /* purpose here is to traverse tree, visiting child nodes before their
00715            parents, this order is necessary for e.g. computing bounding boxes */
00716 
00717         while(iter->stacksize) {
00718                 /* pop node */
00719                 iter->stacksize--;
00720                 node= iter->stack[iter->stacksize].node;
00721 
00722                 /* on a mesh with no faces this can happen
00723                  * can remove this check if we know meshes have at least 1 face */
00724                 if(node==NULL)
00725                         return NULL;
00726 
00727                 revisiting= iter->stack[iter->stacksize].revisiting;
00728 
00729                 /* revisiting node already checked */
00730                 if(revisiting)
00731                         return node;
00732 
00733                 if(iter->scb && !iter->scb(node, iter->search_data))
00734                         continue; /* don't traverse, outside of search zone */
00735 
00736                 if(node->flag & PBVH_Leaf) {
00737                         /* immediately hit leaf node */
00738                         return node;
00739                 }
00740                 else {
00741                         /* come back later when children are done */
00742                         pbvh_stack_push(iter, node, 1);
00743 
00744                         /* push two child nodes on the stack */
00745                         pbvh_stack_push(iter, iter->bvh->nodes+node->children_offset+1, 0);
00746                         pbvh_stack_push(iter, iter->bvh->nodes+node->children_offset, 0);
00747                 }
00748         }
00749 
00750         return NULL;
00751 }
00752 
00753 static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
00754 {
00755         PBVHNode *node;
00756 
00757         while(iter->stacksize) {
00758                 /* pop node */
00759                 iter->stacksize--;
00760                 node= iter->stack[iter->stacksize].node;
00761 
00762                 /* on a mesh with no faces this can happen
00763                  * can remove this check if we know meshes have at least 1 face */
00764                 if(node==NULL) return NULL;
00765 
00766                 if(iter->scb && !iter->scb(node, iter->search_data)) continue; /* don't traverse, outside of search zone */
00767 
00768                 if(node->flag & PBVH_Leaf) {
00769                         /* immediately hit leaf node */
00770                         return node;
00771                 }
00772                 else {
00773                         pbvh_stack_push(iter, iter->bvh->nodes+node->children_offset+1, 0);
00774                         pbvh_stack_push(iter, iter->bvh->nodes+node->children_offset, 0);
00775                 }
00776         }
00777 
00778         return NULL;
00779 }
00780 
00781 void BLI_pbvh_search_gather(PBVH *bvh,
00782         BLI_pbvh_SearchCallback scb, void *search_data,
00783         PBVHNode ***r_array, int *r_tot)
00784 {
00785         PBVHIter iter;
00786         PBVHNode **array= NULL, **newarray, *node;
00787         int tot= 0, space= 0;
00788 
00789         pbvh_iter_begin(&iter, bvh, scb, search_data);
00790 
00791         while((node=pbvh_iter_next(&iter))) {
00792                 if(node->flag & PBVH_Leaf) {
00793                         if(tot == space) {
00794                                 /* resize array if needed */
00795                                 space= (tot == 0)? 32: space*2;
00796                                 newarray= MEM_callocN(sizeof(PBVHNode)*space, "PBVHNodeSearch");
00797 
00798                                 if(array) {
00799                                         memcpy(newarray, array, sizeof(PBVHNode)*tot);
00800                                         MEM_freeN(array);
00801                                 }
00802 
00803                                 array= newarray;
00804                         }
00805 
00806                         array[tot]= node;
00807                         tot++;
00808                 }
00809         }
00810 
00811         pbvh_iter_end(&iter);
00812 
00813         if(tot == 0 && array) {
00814                 MEM_freeN(array);
00815                 array= NULL;
00816         }
00817 
00818         *r_array= array;
00819         *r_tot= tot;
00820 }
00821 
00822 void BLI_pbvh_search_callback(PBVH *bvh,
00823         BLI_pbvh_SearchCallback scb, void *search_data,
00824         BLI_pbvh_HitCallback hcb, void *hit_data)
00825 {
00826         PBVHIter iter;
00827         PBVHNode *node;
00828 
00829         pbvh_iter_begin(&iter, bvh, scb, search_data);
00830 
00831         while((node=pbvh_iter_next(&iter)))
00832                 if (node->flag & PBVH_Leaf)
00833                         hcb(node, hit_data);
00834 
00835         pbvh_iter_end(&iter);
00836 }
00837 
00838 typedef struct node_tree {
00839         PBVHNode* data;
00840 
00841         struct node_tree* left;
00842         struct node_tree* right;
00843 } node_tree;
00844 
00845 static void node_tree_insert(node_tree* tree, node_tree* new_node)
00846 {
00847         if (new_node->data->tmin < tree->data->tmin) {
00848                 if (tree->left) {
00849                         node_tree_insert(tree->left, new_node);
00850                 }
00851                 else {
00852                         tree->left = new_node;
00853                 }
00854         }
00855         else {
00856                 if (tree->right) {
00857                         node_tree_insert(tree->right, new_node);
00858                 }
00859                 else {
00860                         tree->right = new_node;
00861                 }
00862         }
00863 }
00864 
00865 static void traverse_tree(node_tree* tree, BLI_pbvh_HitOccludedCallback hcb, void* hit_data, float* tmin)
00866 {
00867         if (tree->left) traverse_tree(tree->left, hcb, hit_data, tmin);
00868 
00869         hcb(tree->data, hit_data, tmin);
00870 
00871         if (tree->right) traverse_tree(tree->right, hcb, hit_data, tmin);
00872 }
00873 
00874 static void free_tree(node_tree* tree)
00875 {
00876         if (tree->left) {
00877                 free_tree(tree->left);
00878                 tree->left = 0;
00879         }
00880 
00881         if (tree->right) {
00882                 free_tree(tree->right);
00883                 tree->right = 0;
00884         }
00885 
00886         free(tree);
00887 }
00888 
00889 float BLI_pbvh_node_get_tmin(PBVHNode* node)
00890 {
00891         return node->tmin;
00892 }
00893 
00894 static void BLI_pbvh_search_callback_occluded(PBVH *bvh,
00895         BLI_pbvh_SearchCallback scb, void *search_data,
00896         BLI_pbvh_HitOccludedCallback hcb, void *hit_data)
00897 {
00898         PBVHIter iter;
00899         PBVHNode *node;
00900         node_tree *tree = 0;
00901 
00902         pbvh_iter_begin(&iter, bvh, scb, search_data);
00903 
00904         while((node=pbvh_iter_next_occluded(&iter))) {
00905                 if(node->flag & PBVH_Leaf) {
00906                         node_tree* new_node = malloc(sizeof(node_tree));
00907 
00908                         new_node->data = node;
00909 
00910                         new_node->left  = NULL;
00911                         new_node->right = NULL;
00912 
00913                         if (tree) {
00914                                 node_tree_insert(tree, new_node);
00915                         }
00916                         else {
00917                                 tree = new_node;
00918                         }
00919                 }
00920         }
00921 
00922         pbvh_iter_end(&iter);
00923 
00924         if (tree) {
00925                 float tmin = FLT_MAX;
00926                 traverse_tree(tree, hcb, hit_data, &tmin);
00927                 free_tree(tree);
00928         }
00929 }
00930 
00931 static int update_search_cb(PBVHNode *node, void *data_v)
00932 {
00933         int flag= GET_INT_FROM_POINTER(data_v);
00934 
00935         if(node->flag & PBVH_Leaf)
00936                 return (node->flag & flag);
00937         
00938         return 1;
00939 }
00940 
00941 static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
00942         int totnode, float (*face_nors)[3])
00943 {
00944         float (*vnor)[3];
00945         int n;
00946 
00947         if(bvh->grids)
00948                 return;
00949 
00950         /* could be per node to save some memory, but also means
00951            we have to store for each vertex which node it is in */
00952         vnor= MEM_callocN(sizeof(float)*3*bvh->totvert, "bvh temp vnors");
00953 
00954         /* subtle assumptions:
00955            - We know that for all edited vertices, the nodes with faces
00956                  adjacent to these vertices have been marked with PBVH_UpdateNormals.
00957                  This is true because if the vertex is inside the brush radius, the
00958                  bounding box of it's adjacent faces will be as well.
00959            - However this is only true for the vertices that have actually been
00960                  edited, not for all vertices in the nodes marked for update, so we
00961                  can only update vertices marked with ME_VERT_PBVH_UPDATE.
00962         */
00963 
00964         #pragma omp parallel for private(n) schedule(static)
00965         for(n = 0; n < totnode; n++) {
00966                 PBVHNode *node= nodes[n];
00967 
00968                 if((node->flag & PBVH_UpdateNormals)) {
00969                         int i, j, totface, *faces;
00970 
00971                         faces= node->prim_indices;
00972                         totface= node->totprim;
00973 
00974                         for(i = 0; i < totface; ++i) {
00975                                 MFace *f= bvh->faces + faces[i];
00976                                 float fn[3];
00977                                 unsigned int *fv = &f->v1;
00978                                 int sides= (f->v4)? 4: 3;
00979 
00980                                 if(f->v4)
00981                                         normal_quad_v3(fn, bvh->verts[f->v1].co, bvh->verts[f->v2].co,
00982                                                                    bvh->verts[f->v3].co, bvh->verts[f->v4].co);
00983                                 else
00984                                         normal_tri_v3(fn, bvh->verts[f->v1].co, bvh->verts[f->v2].co,
00985                                                                   bvh->verts[f->v3].co);
00986 
00987                                 for(j = 0; j < sides; ++j) {
00988                                         int v= fv[j];
00989 
00990                                         if(bvh->verts[v].flag & ME_VERT_PBVH_UPDATE) {
00991                                                 /* this seems like it could be very slow but profile
00992                                                    does not show this, so just leave it for now? */
00993                                                 #pragma omp atomic
00994                                                 vnor[v][0] += fn[0];
00995                                                 #pragma omp atomic
00996                                                 vnor[v][1] += fn[1];
00997                                                 #pragma omp atomic
00998                                                 vnor[v][2] += fn[2];
00999                                         }
01000                                 }
01001 
01002                                 if(face_nors)
01003                                         copy_v3_v3(face_nors[faces[i]], fn);
01004                         }
01005                 }
01006         }
01007 
01008         #pragma omp parallel for private(n) schedule(static)
01009         for(n = 0; n < totnode; n++) {
01010                 PBVHNode *node= nodes[n];
01011 
01012                 if(node->flag & PBVH_UpdateNormals) {
01013                         int i, *verts, totvert;
01014 
01015                         verts= node->vert_indices;
01016                         totvert= node->uniq_verts;
01017 
01018                         for(i = 0; i < totvert; ++i) {
01019                                 const int v = verts[i];
01020                                 MVert *mvert= &bvh->verts[v];
01021 
01022                                 if(mvert->flag & ME_VERT_PBVH_UPDATE) {
01023                                         float no[3];
01024 
01025                                         copy_v3_v3(no, vnor[v]);
01026                                         normalize_v3(no);
01027                                         
01028                                         mvert->no[0] = (short)(no[0]*32767.0f);
01029                                         mvert->no[1] = (short)(no[1]*32767.0f);
01030                                         mvert->no[2] = (short)(no[2]*32767.0f);
01031                                         
01032                                         mvert->flag &= ~ME_VERT_PBVH_UPDATE;
01033                                 }
01034                         }
01035 
01036                         node->flag &= ~PBVH_UpdateNormals;
01037                 }
01038         }
01039 
01040         MEM_freeN(vnor);
01041 }
01042 
01043 static void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes,
01044         int totnode, int flag)
01045 {
01046         int n;
01047 
01048         /* update BB, redraw flag */
01049         #pragma omp parallel for private(n) schedule(static)
01050         for(n = 0; n < totnode; n++) {
01051                 PBVHNode *node= nodes[n];
01052 
01053                 if((flag & PBVH_UpdateBB) && (node->flag & PBVH_UpdateBB))
01054                         /* don't clear flag yet, leave it for flushing later */
01055                         update_node_vb(bvh, node);
01056 
01057                 if((flag & PBVH_UpdateOriginalBB) && (node->flag & PBVH_UpdateOriginalBB))
01058                         node->orig_vb= node->vb;
01059 
01060                 if((flag & PBVH_UpdateRedraw) && (node->flag & PBVH_UpdateRedraw))
01061                         node->flag &= ~PBVH_UpdateRedraw;
01062         }
01063 }
01064 
01065 static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode, int smooth)
01066 {
01067         PBVHNode *node;
01068         int n;
01069 
01070         /* can't be done in parallel with OpenGL */
01071         for(n = 0; n < totnode; n++) {
01072                 node= nodes[n];
01073 
01074                 if(node->flag & PBVH_UpdateDrawBuffers) {
01075                         if(bvh->grids) {
01076                                 GPU_update_grid_buffers(node->draw_buffers,
01077                                                    bvh->grids,
01078                                                    node->prim_indices,
01079                                                    node->totprim,
01080                                                    bvh->gridsize,
01081                                                    smooth);
01082                         }
01083                         else {
01084                                 GPU_update_mesh_buffers(node->draw_buffers,
01085                                                    bvh->verts,
01086                                                    node->vert_indices,
01087                                                    node->uniq_verts +
01088                                                    node->face_verts);
01089                         }
01090 
01091                         node->flag &= ~PBVH_UpdateDrawBuffers;
01092                 }
01093         }
01094 }
01095 
01096 static int pbvh_flush_bb(PBVH *bvh, PBVHNode *node, int flag)
01097 {
01098         int update= 0;
01099 
01100         /* difficult to multithread well, we just do single threaded recursive */
01101         if(node->flag & PBVH_Leaf) {
01102                 if(flag & PBVH_UpdateBB) {
01103                         update |= (node->flag & PBVH_UpdateBB);
01104                         node->flag &= ~PBVH_UpdateBB;
01105                 }
01106 
01107                 if(flag & PBVH_UpdateOriginalBB) {
01108                         update |= (node->flag & PBVH_UpdateOriginalBB);
01109                         node->flag &= ~PBVH_UpdateOriginalBB;
01110                 }
01111 
01112                 return update;
01113         }
01114         else {
01115                 update |= pbvh_flush_bb(bvh, bvh->nodes + node->children_offset, flag);
01116                 update |= pbvh_flush_bb(bvh, bvh->nodes + node->children_offset + 1, flag);
01117 
01118                 if(update & PBVH_UpdateBB)
01119                         update_node_vb(bvh, node);
01120                 if(update & PBVH_UpdateOriginalBB)
01121                         node->orig_vb= node->vb;
01122         }
01123 
01124         return update;
01125 }
01126 
01127 void BLI_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
01128 {
01129         PBVHNode **nodes;
01130         int totnode;
01131 
01132         BLI_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(flag),
01133                 &nodes, &totnode);
01134 
01135         if(flag & PBVH_UpdateNormals)
01136                 pbvh_update_normals(bvh, nodes, totnode, face_nors);
01137 
01138         if(flag & (PBVH_UpdateBB|PBVH_UpdateOriginalBB|PBVH_UpdateRedraw))
01139                 pbvh_update_BB_redraw(bvh, nodes, totnode, flag);
01140 
01141         if(flag & (PBVH_UpdateBB|PBVH_UpdateOriginalBB))
01142                 pbvh_flush_bb(bvh, bvh->nodes, flag);
01143 
01144         if(nodes) MEM_freeN(nodes);
01145 }
01146 
01147 void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3])
01148 {
01149         PBVHIter iter;
01150         PBVHNode *node;
01151         BB bb;
01152 
01153         BB_reset(&bb);
01154 
01155         pbvh_iter_begin(&iter, bvh, NULL, NULL);
01156 
01157         while((node=pbvh_iter_next(&iter)))
01158                 if(node->flag & PBVH_UpdateRedraw)
01159                         BB_expand_with_bb(&bb, &node->vb);
01160 
01161         pbvh_iter_end(&iter);
01162 
01163         copy_v3_v3(bb_min, bb.bmin);
01164         copy_v3_v3(bb_max, bb.bmax);
01165 }
01166 
01167 void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface)
01168 {
01169         PBVHIter iter;
01170         PBVHNode *node;
01171         GHashIterator *hiter;
01172         GHash *map;
01173         void *face, **faces;
01174         unsigned i;
01175         int tot;
01176 
01177         map = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "pbvh_get_grid_updates gh");
01178 
01179         pbvh_iter_begin(&iter, bvh, NULL, NULL);
01180 
01181         while((node=pbvh_iter_next(&iter))) {
01182                 if(node->flag & PBVH_UpdateNormals) {
01183                         for(i = 0; i < node->totprim; ++i) {
01184                                 face= bvh->gridfaces[node->prim_indices[i]];
01185                                 if(!BLI_ghash_lookup(map, face))
01186                                         BLI_ghash_insert(map, face, face);
01187                         }
01188 
01189                         if(clear)
01190                                 node->flag &= ~PBVH_UpdateNormals;
01191                 }
01192         }
01193 
01194         pbvh_iter_end(&iter);
01195         
01196         tot= BLI_ghash_size(map);
01197         if(tot == 0) {
01198                 *totface= 0;
01199                 *gridfaces= NULL;
01200                 BLI_ghash_free(map, NULL, NULL);
01201                 return;
01202         }
01203 
01204         faces= MEM_callocN(sizeof(void*)*tot, "PBVH Grid Faces");
01205 
01206         for(hiter = BLI_ghashIterator_new(map), i = 0;
01207                 !BLI_ghashIterator_isDone(hiter);
01208                 BLI_ghashIterator_step(hiter), ++i)
01209                 faces[i]= BLI_ghashIterator_getKey(hiter);
01210 
01211         BLI_ghashIterator_free(hiter);
01212 
01213         BLI_ghash_free(map, NULL, NULL);
01214 
01215         *totface= tot;
01216         *gridfaces= faces;
01217 }
01218 
01219 /***************************** Node Access ***********************************/
01220 
01221 void BLI_pbvh_node_mark_update(PBVHNode *node)
01222 {
01223         node->flag |= PBVH_UpdateNormals|PBVH_UpdateBB|PBVH_UpdateOriginalBB|PBVH_UpdateDrawBuffers|PBVH_UpdateRedraw;
01224 }
01225 
01226 void BLI_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node, int **vert_indices, MVert **verts)
01227 {
01228         if(vert_indices) *vert_indices= node->vert_indices;
01229         if(verts) *verts= bvh->verts;
01230 }
01231 
01232 void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *totvert)
01233 {
01234         if(bvh->grids) {
01235                 const int tot= node->totprim*bvh->gridsize*bvh->gridsize;
01236                 if(totvert) *totvert= tot;
01237                 if(uniquevert) *uniquevert= tot;
01238         }
01239         else {
01240                 if(totvert) *totvert= node->uniq_verts + node->face_verts;
01241                 if(uniquevert) *uniquevert= node->uniq_verts;
01242         }
01243 }
01244 
01245 void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, DMGridData ***griddata, DMGridAdjacency **gridadj)
01246 {
01247         if(bvh->grids) {
01248                 if(grid_indices) *grid_indices= node->prim_indices;
01249                 if(totgrid) *totgrid= node->totprim;
01250                 if(maxgrid) *maxgrid= bvh->totgrid;
01251                 if(gridsize) *gridsize= bvh->gridsize;
01252                 if(griddata) *griddata= bvh->grids;
01253                 if(gridadj) *gridadj= bvh->gridadj;
01254         }
01255         else {
01256                 if(grid_indices) *grid_indices= NULL;
01257                 if(totgrid) *totgrid= 0;
01258                 if(maxgrid) *maxgrid= 0;
01259                 if(gridsize) *gridsize= 0;
01260                 if(griddata) *griddata= NULL;
01261                 if(gridadj) *gridadj= NULL;
01262         }
01263 }
01264 
01265 void BLI_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
01266 {
01267         copy_v3_v3(bb_min, node->vb.bmin);
01268         copy_v3_v3(bb_max, node->vb.bmax);
01269 }
01270 
01271 void BLI_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
01272 {
01273         copy_v3_v3(bb_min, node->orig_vb.bmin);
01274         copy_v3_v3(bb_max, node->orig_vb.bmax);
01275 }
01276 
01277 void BLI_pbvh_node_get_proxies(PBVHNode* node, PBVHProxyNode** proxies, int* proxy_count)
01278 {
01279         if (node->proxy_count > 0) {
01280                 if (proxies) *proxies = node->proxies;
01281                 if (proxy_count) *proxy_count = node->proxy_count;
01282         }
01283         else {
01284                 if (proxies) *proxies = 0;
01285                 if (proxy_count) *proxy_count = 0;
01286         }
01287 }
01288 
01289 /********************************* Raycast ***********************************/
01290 
01291 typedef struct {
01292         /* Ray */
01293         float start[3];
01294         int sign[3];
01295         float inv_dir[3];
01296         int original;
01297 } RaycastData;
01298 
01299 /* Adapted from here: http://www.gamedev.net/community/forums/topic.asp?topic_id=459973 */
01300 static int ray_aabb_intersect(PBVHNode *node, void *data_v)
01301 {
01302         RaycastData *ray = data_v;
01303         float bbox[2][3];
01304         float tmin, tmax, tymin, tymax, tzmin, tzmax;
01305 
01306         if(ray->original)
01307                 BLI_pbvh_node_get_original_BB(node, bbox[0], bbox[1]);
01308         else
01309                 BLI_pbvh_node_get_BB(node, bbox[0], bbox[1]);
01310 
01311         tmin = (bbox[ray->sign[0]][0] - ray->start[0]) * ray->inv_dir[0];
01312         tmax = (bbox[1-ray->sign[0]][0] - ray->start[0]) * ray->inv_dir[0];
01313 
01314         tymin = (bbox[ray->sign[1]][1] - ray->start[1]) * ray->inv_dir[1];
01315         tymax = (bbox[1-ray->sign[1]][1] - ray->start[1]) * ray->inv_dir[1];
01316 
01317         if((tmin > tymax) || (tymin > tmax))
01318                 return 0;
01319 
01320         if(tymin > tmin)
01321                 tmin = tymin;
01322 
01323         if(tymax < tmax)
01324                 tmax = tymax;
01325 
01326         tzmin = (bbox[ray->sign[2]][2] - ray->start[2]) * ray->inv_dir[2];
01327         tzmax = (bbox[1-ray->sign[2]][2] - ray->start[2]) * ray->inv_dir[2];
01328 
01329         if((tmin > tzmax) || (tzmin > tmax))
01330                 return 0;
01331 
01332         if(tzmin > tmin)
01333                 tmin = tzmin;
01334 
01335         // XXX jwilkins: tmax does not need to be updated since we don't use it
01336         // keeping this here for future reference
01337         //if(tzmax < tmax) tmax = tzmax; 
01338 
01339         node->tmin = tmin;
01340 
01341         return 1;
01342 }
01343 
01344 void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
01345                           float ray_start[3], float ray_normal[3], int original)
01346 {
01347         RaycastData rcd;
01348 
01349         copy_v3_v3(rcd.start, ray_start);
01350         rcd.inv_dir[0] = 1.0f / ray_normal[0];
01351         rcd.inv_dir[1] = 1.0f / ray_normal[1];
01352         rcd.inv_dir[2] = 1.0f / ray_normal[2];
01353         rcd.sign[0] = rcd.inv_dir[0] < 0;
01354         rcd.sign[1] = rcd.inv_dir[1] < 0;
01355         rcd.sign[2] = rcd.inv_dir[2] < 0;
01356         rcd.original = original;
01357 
01358         BLI_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
01359 }
01360 
01361 static int ray_face_intersection(float ray_start[3], float ray_normal[3],
01362                                  float *t0, float *t1, float *t2, float *t3,
01363                                  float *fdist)
01364 {
01365         float dist;
01366 
01367         if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2, &dist, NULL, 0.1f) && dist < *fdist) ||
01368            (t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist, NULL, 0.1f) && dist < *fdist))
01369         {
01370                 *fdist = dist;
01371                 return 1;
01372         }
01373         else {
01374                 return 0;
01375         }
01376 }
01377 
01378 int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
01379         float ray_start[3], float ray_normal[3], float *dist)
01380 {
01381         int hit= 0;
01382 
01383         if(bvh->faces) {
01384                 MVert *vert = bvh->verts;
01385                 int *faces= node->prim_indices;
01386                 int totface= node->totprim;
01387                 int i;
01388 
01389                 for(i = 0; i < totface; ++i) {
01390                         MFace *f = bvh->faces + faces[i];
01391                         int *face_verts = node->face_vert_indices[i];
01392 
01393                         if(origco) {
01394                                 /* intersect with backuped original coordinates */
01395                                 hit |= ray_face_intersection(ray_start, ray_normal,
01396                                                          origco[face_verts[0]],
01397                                                          origco[face_verts[1]],
01398                                                          origco[face_verts[2]],
01399                                                          f->v4? origco[face_verts[3]]: NULL,
01400                                                          dist);
01401                         }
01402                         else {
01403                                 /* intersect with current coordinates */
01404                                 hit |= ray_face_intersection(ray_start, ray_normal,
01405                                                          vert[f->v1].co,
01406                                                          vert[f->v2].co,
01407                                                          vert[f->v3].co,
01408                                                          f->v4 ? vert[f->v4].co : NULL,
01409                                                          dist);
01410                         }
01411                 }
01412         }
01413         else {
01414                 int totgrid= node->totprim;
01415                 int gridsize= bvh->gridsize;
01416                 int i, x, y;
01417 
01418                 for(i = 0; i < totgrid; ++i) {
01419                         DMGridData *grid= bvh->grids[node->prim_indices[i]];
01420                         if (!grid)
01421                                 continue;
01422 
01423                         for(y = 0; y < gridsize-1; ++y) {
01424                                 for(x = 0; x < gridsize-1; ++x) {
01425                                         if(origco) {
01426                                                 hit |= ray_face_intersection(ray_start, ray_normal,
01427                                                                          origco[y*gridsize + x],
01428                                                                          origco[y*gridsize + x+1],
01429                                                                          origco[(y+1)*gridsize + x+1],
01430                                                                          origco[(y+1)*gridsize + x],
01431                                                                          dist);
01432                                         }
01433                                         else {
01434                                                 hit |= ray_face_intersection(ray_start, ray_normal,
01435                                                                          grid[y*gridsize + x].co,
01436                                                                          grid[y*gridsize + x+1].co,
01437                                                                          grid[(y+1)*gridsize + x+1].co,
01438                                                                          grid[(y+1)*gridsize + x].co,
01439                                                                          dist);
01440                                         }
01441                                 }
01442                         }
01443 
01444                         if(origco)
01445                                 origco += gridsize*gridsize;
01446                 }
01447         }
01448 
01449         return hit;
01450 }
01451 
01452 //#include <GL/glew.h>
01453 
01454 void BLI_pbvh_node_draw(PBVHNode *node, void *UNUSED(data))
01455 {
01456 #if 0
01457         /* XXX: Just some quick code to show leaf nodes in different colors */
01458         float col[3]; int i;
01459 
01460         if(0) { //is_partial) {
01461                 col[0] = (rand() / (float)RAND_MAX); col[1] = col[2] = 0.6;
01462         }
01463         else {
01464                 srand((long long)node);
01465                 for(i = 0; i < 3; ++i)
01466                         col[i] = (rand() / (float)RAND_MAX) * 0.3 + 0.7;
01467         }
01468         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
01469 
01470         glColor3f(1, 0, 0);
01471 #endif
01472         GPU_draw_buffers(node->draw_buffers);
01473 }
01474 
01475 /* Adapted from:
01476    http://www.gamedev.net/community/forums/topic.asp?topic_id=512123
01477    Returns true if the AABB is at least partially within the frustum
01478    (ok, not a real frustum), false otherwise.
01479 */
01480 int BLI_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data)
01481 {
01482         float (*planes)[4] = data;
01483         int i, axis;
01484         float vmin[3] /*, vmax[3]*/, bb_min[3], bb_max[3];
01485 
01486         BLI_pbvh_node_get_BB(node, bb_min, bb_max);
01487 
01488         for(i = 0; i < 4; ++i) { 
01489                 for(axis = 0; axis < 3; ++axis) {
01490                         if(planes[i][axis] > 0) { 
01491                                 vmin[axis] = bb_min[axis];
01492                                 /*vmax[axis] = bb_max[axis];*/ /*UNUSED*/
01493                         }
01494                         else {
01495                                 vmin[axis] = bb_max[axis];
01496                                 /*vmax[axis] = bb_min[axis];*/ /*UNUSED*/
01497                         }
01498                 }
01499                 
01500                 if(dot_v3v3(planes[i], vmin) + planes[i][3] > 0)
01501                         return 0;
01502         } 
01503 
01504         return 1;
01505 }
01506 
01507 void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3], int smooth)
01508 {
01509         PBVHNode **nodes;
01510         int totnode;
01511 
01512         BLI_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals|PBVH_UpdateDrawBuffers),
01513                 &nodes, &totnode);
01514 
01515         pbvh_update_normals(bvh, nodes, totnode, face_nors);
01516         pbvh_update_draw_buffers(bvh, nodes, totnode, smooth);
01517 
01518         if(nodes) MEM_freeN(nodes);
01519 
01520         if(planes) {
01521                 BLI_pbvh_search_callback(bvh, BLI_pbvh_node_planes_contain_AABB,
01522                                 planes, BLI_pbvh_node_draw, NULL);
01523         }
01524         else {
01525                 BLI_pbvh_search_callback(bvh, NULL, NULL, BLI_pbvh_node_draw, NULL);
01526         }
01527 }
01528 
01529 void BLI_pbvh_grids_update(PBVH *bvh, DMGridData **grids, DMGridAdjacency *gridadj, void **gridfaces)
01530 {
01531         bvh->grids= grids;
01532         bvh->gridadj= gridadj;
01533         bvh->gridfaces= gridfaces;
01534 }
01535 
01536 float (*BLI_pbvh_get_vertCos(PBVH *pbvh))[3]
01537 {
01538         int a;
01539         float (*vertCos)[3]= NULL;
01540 
01541         if (pbvh->verts) {
01542                 float *co;
01543                 MVert *mvert= pbvh->verts;
01544 
01545                 vertCos= MEM_callocN(3*pbvh->totvert*sizeof(float), "BLI_pbvh_get_vertCoords");
01546                 co= (float*)vertCos;
01547 
01548                 for (a= 0; a<pbvh->totvert; a++, mvert++, co+= 3) {
01549                         copy_v3_v3(co, mvert->co);
01550                 }
01551         }
01552 
01553         return vertCos;
01554 }
01555 
01556 void BLI_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
01557 {
01558         int a;
01559 
01560         if (!pbvh->deformed) {
01561                 if (pbvh->verts) {
01562                         /* if pbvh is not already deformed, verts/faces points to the */
01563                         /* original data and applying new coords to this arrays would lead to */
01564                         /* unneeded deformation -- duplicate verts/faces to avoid this */
01565 
01566                         pbvh->verts= MEM_dupallocN(pbvh->verts);
01567                         pbvh->faces= MEM_dupallocN(pbvh->faces);
01568 
01569                         pbvh->deformed= 1;
01570                 }
01571         }
01572 
01573         if (pbvh->verts) {
01574                 MVert *mvert= pbvh->verts;
01575                 /* copy new verts coords */
01576                 for (a= 0; a < pbvh->totvert; ++a, ++mvert) {
01577                         copy_v3_v3(mvert->co, vertCos[a]);
01578                         mvert->flag |= ME_VERT_PBVH_UPDATE;
01579                 }
01580 
01581                 /* coordinates are new -- normals should also be updated */
01582                 mesh_calc_normals(pbvh->verts, pbvh->totvert, pbvh->faces, pbvh->totprim, NULL);
01583 
01584                 for (a= 0; a < pbvh->totnode; ++a)
01585                         BLI_pbvh_node_mark_update(&pbvh->nodes[a]);
01586 
01587                 BLI_pbvh_update(pbvh, PBVH_UpdateBB, NULL);
01588                 BLI_pbvh_update(pbvh, PBVH_UpdateOriginalBB, NULL);
01589 
01590         }
01591 }
01592 
01593 int BLI_pbvh_isDeformed(PBVH *pbvh)
01594 {
01595         return pbvh->deformed;
01596 }
01597 /* Proxies */
01598 
01599 PBVHProxyNode* BLI_pbvh_node_add_proxy(PBVH* bvh, PBVHNode* node)
01600 {
01601         int index, totverts;
01602 
01603         #pragma omp critical
01604         {
01605 
01606                 index = node->proxy_count;
01607 
01608                 node->proxy_count++;
01609 
01610                 if (node->proxies)
01611                         node->proxies= MEM_reallocN(node->proxies, node->proxy_count*sizeof(PBVHProxyNode));
01612                 else
01613                         node->proxies= MEM_mallocN(sizeof(PBVHProxyNode), "PBVHNodeProxy");
01614 
01615                 if (bvh->grids)
01616                         totverts = node->totprim*bvh->gridsize*bvh->gridsize;
01617                 else
01618                         totverts = node->uniq_verts;
01619 
01620                 node->proxies[index].co= MEM_callocN(sizeof(float[3])*totverts, "PBVHNodeProxy.co");
01621         }
01622 
01623         return node->proxies + index;
01624 }
01625 
01626 void BLI_pbvh_node_free_proxies(PBVHNode* node)
01627 {
01628         #pragma omp critical
01629         {
01630                 int p;
01631 
01632                 for (p= 0; p < node->proxy_count; p++) {
01633                         MEM_freeN(node->proxies[p].co);
01634                         node->proxies[p].co= 0;
01635                 }
01636 
01637                 MEM_freeN(node->proxies);
01638                 node->proxies = 0;
01639 
01640                 node->proxy_count= 0;
01641         }
01642 }
01643 
01644 void BLI_pbvh_gather_proxies(PBVH* pbvh, PBVHNode*** r_array,  int* r_tot)
01645 {
01646         PBVHNode **array= NULL, **newarray, *node;
01647         int tot= 0, space= 0;
01648         int n;
01649 
01650         for (n= 0; n < pbvh->totnode; n++) {
01651                 node = pbvh->nodes + n;
01652 
01653                 if(node->proxy_count > 0) {
01654                         if(tot == space) {
01655                                 /* resize array if needed */
01656                                 space= (tot == 0)? 32: space*2;
01657                                 newarray= MEM_callocN(sizeof(PBVHNode)*space, "BLI_pbvh_gather_proxies");
01658 
01659                                 if (array) {
01660                                         memcpy(newarray, array, sizeof(PBVHNode)*tot);
01661                                         MEM_freeN(array);
01662                                 }
01663 
01664                                 array= newarray;
01665                         }
01666 
01667                         array[tot]= node;
01668                         tot++;
01669                 }
01670         }
01671 
01672         if(tot == 0 && array) {
01673                 MEM_freeN(array);
01674                 array= NULL;
01675         }
01676 
01677         *r_array= array;
01678         *r_tot= tot;
01679 }