Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
/**
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
#include "DNA_meshdata_types.h"
|
|
|
|
|
2010-08-16 05:46:10 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2009-11-11 10:44:46 +00:00
|
|
|
#include "BLI_math.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2009-10-27 19:53:34 +00:00
|
|
|
#include "BLI_ghash.h"
|
|
|
|
#include "BLI_pbvh.h"
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
#include "BKE_DerivedMesh.h"
|
2010-06-21 20:10:59 +00:00
|
|
|
#include "BKE_mesh.h" /* for mesh_calc_normals */
|
2010-07-01 15:12:10 +00:00
|
|
|
#include "BKE_global.h" /* for mesh_calc_normals */
|
2009-10-27 19:53:34 +00:00
|
|
|
|
2010-07-14 10:46:12 +00:00
|
|
|
#include "GPU_buffers.h"
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
#define LEAF_LIMIT 10000
|
|
|
|
|
|
|
|
//#define PERFCNTRS
|
|
|
|
|
|
|
|
/* Bitmap */
|
|
|
|
typedef char* BLI_bitmap;
|
|
|
|
|
|
|
|
BLI_bitmap BLI_bitmap_new(int tot)
|
|
|
|
{
|
|
|
|
return MEM_callocN((tot >> 3) + 1, "BLI bitmap");
|
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_bitmap_get(BLI_bitmap b, int index)
|
|
|
|
{
|
|
|
|
return b[index >> 3] & (1 << (index & 7));
|
|
|
|
}
|
|
|
|
|
|
|
|
void BLI_bitmap_set(BLI_bitmap b, int index)
|
|
|
|
{
|
|
|
|
b[index >> 3] |= (1 << (index & 7));
|
|
|
|
}
|
|
|
|
|
|
|
|
void BLI_bitmap_clear(BLI_bitmap b, int index)
|
|
|
|
{
|
|
|
|
b[index >> 3] &= ~(1 << (index & 7));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Axis-aligned bounding box */
|
|
|
|
typedef struct {
|
|
|
|
float bmin[3], bmax[3];
|
|
|
|
} BB;
|
|
|
|
|
|
|
|
/* Axis-aligned bounding box with centroid */
|
|
|
|
typedef struct {
|
|
|
|
float bmin[3], bmax[3], bcentroid[3];
|
|
|
|
} BBC;
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
struct PBVHNode {
|
2009-10-27 19:53:34 +00:00
|
|
|
/* Opaque handle for drawing code */
|
|
|
|
void *draw_buffers;
|
|
|
|
|
|
|
|
int *vert_indices;
|
|
|
|
|
|
|
|
/* Voxel bounds */
|
|
|
|
BB vb;
|
2009-11-06 16:46:35 +00:00
|
|
|
BB orig_vb;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
/* For internal nodes */
|
|
|
|
int children_offset;
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
/* Pointer into bvh prim_indices */
|
|
|
|
int *prim_indices;
|
2009-11-06 16:46:35 +00:00
|
|
|
int *face_vert_indices;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
unsigned int totprim;
|
|
|
|
unsigned int uniq_verts, face_verts;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
char flag;
|
2010-07-14 14:11:03 +00:00
|
|
|
|
|
|
|
float tmin; // used for raycasting, is how close bb is to the ray point
|
|
|
|
|
|
|
|
int proxy_count;
|
|
|
|
PBVHProxyNode* proxies;
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
};
|
2009-10-27 19:53:34 +00:00
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
struct PBVH {
|
|
|
|
PBVHNode *nodes;
|
2009-10-27 19:53:34 +00:00
|
|
|
int node_mem_count, totnode;
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
int *prim_indices;
|
|
|
|
int totprim;
|
2009-11-04 20:36:38 +00:00
|
|
|
int totvert;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
int leaf_limit;
|
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
/* Mesh data */
|
|
|
|
MVert *verts;
|
|
|
|
MFace *faces;
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
/* Grid Data */
|
|
|
|
DMGridData **grids;
|
2009-12-09 13:37:19 +00:00
|
|
|
DMGridAdjacency *gridadj;
|
2009-11-25 13:40:43 +00:00
|
|
|
void **gridfaces;
|
|
|
|
int totgrid;
|
|
|
|
int gridsize;
|
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
/* Only used during BVH build and update,
|
|
|
|
don't need to remain valid after */
|
|
|
|
BLI_bitmap vert_bitmap;
|
|
|
|
|
|
|
|
#ifdef PERFCNTRS
|
|
|
|
int perf_modified;
|
|
|
|
#endif
|
2010-06-21 20:10:59 +00:00
|
|
|
|
|
|
|
/* flag are verts/faces deformed */
|
|
|
|
int deformed;
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#define STACK_FIXED_DEPTH 100
|
|
|
|
|
|
|
|
typedef struct PBVHStack {
|
|
|
|
PBVHNode *node;
|
|
|
|
int revisiting;
|
|
|
|
} PBVHStack;
|
|
|
|
|
|
|
|
typedef struct PBVHIter {
|
|
|
|
PBVH *bvh;
|
|
|
|
BLI_pbvh_SearchCallback scb;
|
|
|
|
void *search_data;
|
|
|
|
|
|
|
|
PBVHStack *stack;
|
|
|
|
int stacksize;
|
|
|
|
|
|
|
|
PBVHStack stackfixed[STACK_FIXED_DEPTH];
|
|
|
|
int stackspace;
|
|
|
|
} PBVHIter;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
static void BB_reset(BB *bb)
|
|
|
|
{
|
|
|
|
bb->bmin[0] = bb->bmin[1] = bb->bmin[2] = FLT_MAX;
|
|
|
|
bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Expand the bounding box to include a new coordinate */
|
|
|
|
static void BB_expand(BB *bb, float co[3])
|
|
|
|
{
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
int i;
|
|
|
|
for(i = 0; i < 3; ++i) {
|
|
|
|
bb->bmin[i] = MIN2(bb->bmin[i], co[i]);
|
|
|
|
bb->bmax[i] = MAX2(bb->bmax[i], co[i]);
|
|
|
|
}
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Expand the bounding box to include another bounding box */
|
|
|
|
static void BB_expand_with_bb(BB *bb, BB *bb2)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < 3; ++i) {
|
|
|
|
bb->bmin[i] = MIN2(bb->bmin[i], bb2->bmin[i]);
|
|
|
|
bb->bmax[i] = MAX2(bb->bmax[i], bb2->bmax[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return 0, 1, or 2 to indicate the widest axis of the bounding box */
|
|
|
|
static int BB_widest_axis(BB *bb)
|
|
|
|
{
|
|
|
|
float dim[3];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for(i = 0; i < 3; ++i)
|
|
|
|
dim[i] = bb->bmax[i] - bb->bmin[i];
|
|
|
|
|
|
|
|
if(dim[0] > dim[1]) {
|
|
|
|
if(dim[0] > dim[2])
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(dim[1] > dim[2])
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void BBC_update_centroid(BBC *bbc)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < 3; ++i)
|
|
|
|
bbc->bcentroid[i] = (bbc->bmin[i] + bbc->bmax[i]) * 0.5f;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Not recursive */
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
static void update_node_vb(PBVH *bvh, PBVHNode *node)
|
2009-10-27 19:53:34 +00:00
|
|
|
{
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
BB vb;
|
|
|
|
|
|
|
|
BB_reset(&vb);
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
if(node->flag & PBVH_Leaf) {
|
2009-11-25 13:40:43 +00:00
|
|
|
PBVHVertexIter vd;
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
BLI_pbvh_vertex_iter_begin(bvh, node, vd, PBVH_ITER_ALL) {
|
|
|
|
BB_expand(&vb, vd.co);
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
2009-11-25 13:40:43 +00:00
|
|
|
BLI_pbvh_vertex_iter_end;
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
else {
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
BB_expand_with_bb(&vb,
|
2009-10-27 19:53:34 +00:00
|
|
|
&bvh->nodes[node->children_offset].vb);
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
BB_expand_with_bb(&vb,
|
2009-10-27 19:53:34 +00:00
|
|
|
&bvh->nodes[node->children_offset + 1].vb);
|
|
|
|
}
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
|
|
|
node->vb= vb;
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
|
2010-07-14 14:11:03 +00:00
|
|
|
//void BLI_pbvh_node_BB_reset(PBVHNode* node)
|
|
|
|
//{
|
|
|
|
// BB_reset(&node->vb);
|
|
|
|
//}
|
|
|
|
//
|
|
|
|
//void BLI_pbvh_node_BB_expand(PBVHNode* node, float co[3])
|
|
|
|
//{
|
|
|
|
// BB_expand(&node->vb, co);
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
/* Adapted from BLI_kdopbvh.c */
|
|
|
|
/* Returns the index of the first element on the right of the partition */
|
2009-11-25 13:40:43 +00:00
|
|
|
static int partition_indices(int *prim_indices, int lo, int hi, int axis,
|
2010-03-22 09:30:00 +00:00
|
|
|
float mid, BBC *prim_bbc)
|
2009-10-27 19:53:34 +00:00
|
|
|
{
|
|
|
|
int i=lo, j=hi;
|
|
|
|
for(;;) {
|
2009-11-25 13:40:43 +00:00
|
|
|
for(; prim_bbc[prim_indices[i]].bcentroid[axis] < mid; i++);
|
|
|
|
for(; mid < prim_bbc[prim_indices[j]].bcentroid[axis]; j--);
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
if(!(i < j))
|
|
|
|
return i;
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
SWAP(int, prim_indices[i], prim_indices[j]);
|
2009-10-27 19:53:34 +00:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
void check_partitioning(int *prim_indices, int lo, int hi, int axis,
|
2010-03-22 09:30:00 +00:00
|
|
|
float mid, BBC *prim_bbc, int index_of_2nd_partition)
|
2009-10-27 19:53:34 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i = lo; i <= hi; ++i) {
|
2009-11-25 13:40:43 +00:00
|
|
|
const float c = prim_bbc[prim_indices[i]].bcentroid[axis];
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
if((i < index_of_2nd_partition && c > mid) ||
|
|
|
|
(i > index_of_2nd_partition && c < mid)) {
|
|
|
|
printf("fail\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void grow_nodes(PBVH *bvh, int totnode)
|
|
|
|
{
|
|
|
|
if(totnode > bvh->node_mem_count) {
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
PBVHNode *prev = bvh->nodes;
|
2009-10-27 19:53:34 +00:00
|
|
|
bvh->node_mem_count *= 1.33;
|
|
|
|
if(bvh->node_mem_count < totnode)
|
|
|
|
bvh->node_mem_count = totnode;
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
bvh->nodes = MEM_callocN(sizeof(PBVHNode) * bvh->node_mem_count,
|
2009-10-27 19:53:34 +00:00
|
|
|
"bvh nodes");
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
memcpy(bvh->nodes, prev, bvh->totnode * sizeof(PBVHNode));
|
2009-10-27 19:53:34 +00:00
|
|
|
MEM_freeN(prev);
|
|
|
|
}
|
|
|
|
|
|
|
|
bvh->totnode = totnode;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add a vertex to the map, with a positive value for unique vertices and
|
|
|
|
a negative value for additional vertices */
|
2009-11-06 16:46:35 +00:00
|
|
|
static int map_insert_vert(PBVH *bvh, GHash *map,
|
2010-03-22 09:30:00 +00:00
|
|
|
unsigned int *face_verts,
|
|
|
|
unsigned int *uniq_verts, int vertex)
|
2009-10-27 19:53:34 +00:00
|
|
|
{
|
|
|
|
void *value, *key = SET_INT_IN_POINTER(vertex);
|
|
|
|
|
|
|
|
if(!BLI_ghash_haskey(map, key)) {
|
|
|
|
if(BLI_bitmap_get(bvh->vert_bitmap, vertex)) {
|
|
|
|
value = SET_INT_IN_POINTER(-(*face_verts) - 1);
|
|
|
|
++(*face_verts);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
BLI_bitmap_set(bvh->vert_bitmap, vertex);
|
|
|
|
value = SET_INT_IN_POINTER(*uniq_verts);
|
|
|
|
++(*uniq_verts);
|
|
|
|
}
|
|
|
|
|
|
|
|
BLI_ghash_insert(map, key, value);
|
2009-11-06 16:46:35 +00:00
|
|
|
return GET_INT_FROM_POINTER(value);
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
2009-11-06 16:46:35 +00:00
|
|
|
else
|
|
|
|
return GET_INT_FROM_POINTER(BLI_ghash_lookup(map, key));
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Find vertices used by the faces in this node and update the draw buffers */
|
2009-11-25 13:40:43 +00:00
|
|
|
static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
|
2009-10-27 19:53:34 +00:00
|
|
|
{
|
|
|
|
GHashIterator *iter;
|
|
|
|
GHash *map;
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
int i, j, totface;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
2010-05-07 07:54:25 +00:00
|
|
|
map = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "build_mesh_leaf_node gh");
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
node->uniq_verts = node->face_verts = 0;
|
2009-11-25 13:40:43 +00:00
|
|
|
totface= node->totprim;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
node->face_vert_indices = MEM_callocN(sizeof(int) *
|
|
|
|
4*totface, "bvh node face vert indices");
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
for(i = 0; i < totface; ++i) {
|
2009-11-25 13:40:43 +00:00
|
|
|
MFace *f = bvh->faces + node->prim_indices[i];
|
2009-10-27 19:53:34 +00:00
|
|
|
int sides = f->v4 ? 4 : 3;
|
|
|
|
|
|
|
|
for(j = 0; j < sides; ++j) {
|
2009-11-06 16:46:35 +00:00
|
|
|
node->face_vert_indices[i*4 + j]=
|
|
|
|
map_insert_vert(bvh, map, &node->face_verts,
|
|
|
|
&node->uniq_verts, (&f->v1)[j]);
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
node->vert_indices = MEM_callocN(sizeof(int) *
|
|
|
|
(node->uniq_verts + node->face_verts),
|
|
|
|
"bvh node vert indices");
|
|
|
|
|
|
|
|
/* Build the vertex list, unique verts first */
|
|
|
|
for(iter = BLI_ghashIterator_new(map), i = 0;
|
2010-03-22 09:30:00 +00:00
|
|
|
!BLI_ghashIterator_isDone(iter);
|
|
|
|
BLI_ghashIterator_step(iter), ++i) {
|
2009-10-27 19:53:34 +00:00
|
|
|
void *value = BLI_ghashIterator_getValue(iter);
|
|
|
|
int ndx = GET_INT_FROM_POINTER(value);
|
|
|
|
|
|
|
|
if(ndx < 0)
|
|
|
|
ndx = -ndx + node->uniq_verts - 1;
|
|
|
|
|
|
|
|
node->vert_indices[ndx] =
|
|
|
|
GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(iter));
|
|
|
|
}
|
|
|
|
|
2010-02-01 11:36:22 +00:00
|
|
|
BLI_ghashIterator_free(iter);
|
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
for(i = 0; i < totface*4; ++i)
|
|
|
|
if(node->face_vert_indices[i] < 0)
|
|
|
|
node->face_vert_indices[i]= -node->face_vert_indices[i] + node->uniq_verts - 1;
|
|
|
|
|
2010-07-01 15:12:10 +00:00
|
|
|
if(!G.background) {
|
|
|
|
node->draw_buffers =
|
|
|
|
GPU_build_mesh_buffers(map, bvh->verts, bvh->faces,
|
2010-07-14 14:11:03 +00:00
|
|
|
node->prim_indices,
|
|
|
|
node->totprim, node->vert_indices,
|
|
|
|
node->uniq_verts,
|
|
|
|
node->uniq_verts + node->face_verts);
|
2010-07-01 15:12:10 +00:00
|
|
|
}
|
2009-10-27 19:53:34 +00:00
|
|
|
|
2010-03-22 17:17:36 +00:00
|
|
|
node->flag |= PBVH_UpdateDrawBuffers;
|
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
BLI_ghash_free(map, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
static void build_grids_leaf_node(PBVH *bvh, PBVHNode *node)
|
|
|
|
{
|
2010-07-01 15:12:10 +00:00
|
|
|
if(!G.background) {
|
|
|
|
node->draw_buffers =
|
|
|
|
GPU_build_grid_buffers(bvh->grids, node->prim_indices,
|
2009-11-25 13:40:43 +00:00
|
|
|
node->totprim, bvh->gridsize);
|
2010-07-01 15:12:10 +00:00
|
|
|
}
|
2010-03-22 17:17:36 +00:00
|
|
|
node->flag |= PBVH_UpdateDrawBuffers;
|
2009-11-25 13:40:43 +00:00
|
|
|
}
|
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
/* Recursively build a node in the tree
|
|
|
|
|
|
|
|
vb is the voxel box around all of the primitives contained in
|
|
|
|
this node.
|
|
|
|
|
|
|
|
cb is the bounding box around all the centroids of the primitives
|
|
|
|
contained in this node
|
|
|
|
|
|
|
|
offset and start indicate a range in the array of primitive indices
|
|
|
|
*/
|
|
|
|
|
|
|
|
void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
|
2010-03-22 09:30:00 +00:00
|
|
|
int offset, int count)
|
2009-10-27 19:53:34 +00:00
|
|
|
{
|
|
|
|
int i, axis, end;
|
|
|
|
BB cb_backing;
|
|
|
|
|
|
|
|
/* Decide whether this is a leaf or not */
|
2009-11-25 13:40:43 +00:00
|
|
|
// XXX adapt leaf limit for grids
|
|
|
|
if(count <= bvh->leaf_limit) {
|
2009-10-27 19:53:34 +00:00
|
|
|
bvh->nodes[node_index].flag |= PBVH_Leaf;
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
bvh->nodes[node_index].prim_indices = bvh->prim_indices + offset;
|
|
|
|
bvh->nodes[node_index].totprim = count;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
/* Still need vb for searches */
|
|
|
|
BB_reset(&bvh->nodes[node_index].vb);
|
|
|
|
for(i = offset + count - 1; i >= offset; --i) {
|
|
|
|
BB_expand_with_bb(&bvh->nodes[node_index].vb,
|
|
|
|
(BB*)(prim_bbc +
|
2009-11-25 13:40:43 +00:00
|
|
|
bvh->prim_indices[i]));
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
if(bvh->faces)
|
|
|
|
build_mesh_leaf_node(bvh, bvh->nodes + node_index);
|
|
|
|
else
|
|
|
|
build_grids_leaf_node(bvh, bvh->nodes + node_index);
|
2009-11-06 16:46:35 +00:00
|
|
|
bvh->nodes[node_index].orig_vb= bvh->nodes[node_index].vb;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
/* Done with this subtree */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
BB_reset(&bvh->nodes[node_index].vb);
|
|
|
|
bvh->nodes[node_index].children_offset = bvh->totnode;
|
|
|
|
grow_nodes(bvh, bvh->totnode + 2);
|
|
|
|
|
|
|
|
if(!cb) {
|
|
|
|
cb = &cb_backing;
|
|
|
|
BB_reset(cb);
|
|
|
|
for(i = offset + count - 1; i >= offset; --i)
|
2009-11-25 13:40:43 +00:00
|
|
|
BB_expand(cb, prim_bbc[bvh->prim_indices[i]].bcentroid);
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
axis = BB_widest_axis(cb);
|
|
|
|
|
|
|
|
for(i = offset + count - 1; i >= offset; --i) {
|
|
|
|
BB_expand_with_bb(&bvh->nodes[node_index].vb,
|
2009-11-25 13:40:43 +00:00
|
|
|
(BB*)(prim_bbc + bvh->prim_indices[i]));
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
bvh->nodes[node_index].orig_vb= bvh->nodes[node_index].vb;
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
end = partition_indices(bvh->prim_indices, offset, offset + count - 1,
|
2009-10-27 19:53:34 +00:00
|
|
|
axis,
|
|
|
|
(cb->bmax[axis] + cb->bmin[axis]) * 0.5f,
|
|
|
|
prim_bbc);
|
2009-11-25 13:40:43 +00:00
|
|
|
check_partitioning(bvh->prim_indices, offset, offset + count - 1,
|
2009-10-27 19:53:34 +00:00
|
|
|
axis,
|
|
|
|
(cb->bmax[axis] + cb->bmin[axis]) * 0.5f,
|
|
|
|
prim_bbc, end);
|
|
|
|
|
|
|
|
build_sub(bvh, bvh->nodes[node_index].children_offset, NULL,
|
|
|
|
prim_bbc, offset, end - offset);
|
|
|
|
build_sub(bvh, bvh->nodes[node_index].children_offset + 1, NULL,
|
|
|
|
prim_bbc, end, offset + count - end);
|
|
|
|
}
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim)
|
2009-10-27 19:53:34 +00:00
|
|
|
{
|
2009-11-25 13:40:43 +00:00
|
|
|
int i;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
if(totprim != bvh->totprim) {
|
|
|
|
bvh->totprim = totprim;
|
2009-10-27 19:53:34 +00:00
|
|
|
if(bvh->nodes) MEM_freeN(bvh->nodes);
|
2009-11-25 13:40:43 +00:00
|
|
|
if(bvh->prim_indices) MEM_freeN(bvh->prim_indices);
|
|
|
|
bvh->prim_indices = MEM_callocN(sizeof(int) * totprim,
|
|
|
|
"bvh prim indices");
|
|
|
|
for(i = 0; i < totprim; ++i)
|
|
|
|
bvh->prim_indices[i] = i;
|
2009-10-27 19:53:34 +00:00
|
|
|
bvh->totnode = 0;
|
|
|
|
if(bvh->node_mem_count < 100) {
|
|
|
|
bvh->node_mem_count = 100;
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
bvh->nodes = MEM_callocN(sizeof(PBVHNode) *
|
2009-10-27 19:53:34 +00:00
|
|
|
bvh->node_mem_count,
|
|
|
|
"bvh initial nodes");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
bvh->totnode = 1;
|
|
|
|
build_sub(bvh, 0, cb, prim_bbc, 0, totprim);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do a full rebuild with on Mesh data structure */
|
|
|
|
void BLI_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int totvert)
|
|
|
|
{
|
|
|
|
BBC *prim_bbc = NULL;
|
|
|
|
BB cb;
|
|
|
|
int i, j;
|
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
bvh->faces = faces;
|
|
|
|
bvh->verts = verts;
|
|
|
|
bvh->vert_bitmap = BLI_bitmap_new(totvert);
|
2009-11-25 13:40:43 +00:00
|
|
|
bvh->totvert = totvert;
|
|
|
|
bvh->leaf_limit = LEAF_LIMIT;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
BB_reset(&cb);
|
|
|
|
|
|
|
|
/* For each face, store the AABB and the AABB centroid */
|
|
|
|
prim_bbc = MEM_mallocN(sizeof(BBC) * totface, "prim_bbc");
|
|
|
|
|
|
|
|
for(i = 0; i < totface; ++i) {
|
|
|
|
MFace *f = faces + i;
|
|
|
|
const int sides = f->v4 ? 4 : 3;
|
|
|
|
BBC *bbc = prim_bbc + i;
|
|
|
|
|
|
|
|
BB_reset((BB*)bbc);
|
|
|
|
|
|
|
|
for(j = 0; j < sides; ++j)
|
|
|
|
BB_expand((BB*)bbc, verts[(&f->v1)[j]].co);
|
|
|
|
|
|
|
|
BBC_update_centroid(bbc);
|
|
|
|
|
|
|
|
BB_expand(&cb, bbc->bcentroid);
|
|
|
|
}
|
|
|
|
|
2009-12-18 17:15:58 +00:00
|
|
|
if(totface)
|
|
|
|
pbvh_build(bvh, &cb, prim_bbc, totface);
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
MEM_freeN(prim_bbc);
|
|
|
|
MEM_freeN(bvh->vert_bitmap);
|
|
|
|
}
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
/* Do a full rebuild with on Grids data structure */
|
2009-12-09 13:37:19 +00:00
|
|
|
void BLI_pbvh_build_grids(PBVH *bvh, DMGridData **grids, DMGridAdjacency *gridadj,
|
|
|
|
int totgrid, int gridsize, void **gridfaces)
|
2009-11-25 13:40:43 +00:00
|
|
|
{
|
|
|
|
BBC *prim_bbc = NULL;
|
|
|
|
BB cb;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
bvh->grids= grids;
|
2009-12-09 13:37:19 +00:00
|
|
|
bvh->gridadj= gridadj;
|
2009-11-25 13:40:43 +00:00
|
|
|
bvh->gridfaces= gridfaces;
|
|
|
|
bvh->totgrid= totgrid;
|
|
|
|
bvh->gridsize= gridsize;
|
|
|
|
bvh->leaf_limit = MAX2(LEAF_LIMIT/((gridsize-1)*(gridsize-1)), 1);
|
|
|
|
|
|
|
|
BB_reset(&cb);
|
|
|
|
|
|
|
|
/* For each grid, store the AABB and the AABB centroid */
|
|
|
|
prim_bbc = MEM_mallocN(sizeof(BBC) * totgrid, "prim_bbc");
|
|
|
|
|
|
|
|
for(i = 0; i < totgrid; ++i) {
|
|
|
|
DMGridData *grid= grids[i];
|
|
|
|
BBC *bbc = prim_bbc + i;
|
|
|
|
|
|
|
|
BB_reset((BB*)bbc);
|
|
|
|
|
|
|
|
for(j = 0; j < gridsize*gridsize; ++j)
|
|
|
|
BB_expand((BB*)bbc, grid[j].co);
|
|
|
|
|
|
|
|
BBC_update_centroid(bbc);
|
|
|
|
|
|
|
|
BB_expand(&cb, bbc->bcentroid);
|
|
|
|
}
|
|
|
|
|
2009-12-18 17:15:58 +00:00
|
|
|
if(totgrid)
|
|
|
|
pbvh_build(bvh, &cb, prim_bbc, totgrid);
|
2009-11-25 13:40:43 +00:00
|
|
|
|
|
|
|
MEM_freeN(prim_bbc);
|
|
|
|
}
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
PBVH *BLI_pbvh_new(void)
|
2009-10-27 19:53:34 +00:00
|
|
|
{
|
|
|
|
PBVH *bvh = MEM_callocN(sizeof(PBVH), "pbvh");
|
|
|
|
|
|
|
|
return bvh;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BLI_pbvh_free(PBVH *bvh)
|
|
|
|
{
|
2009-11-25 13:40:43 +00:00
|
|
|
PBVHNode *node;
|
2009-10-27 19:53:34 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for(i = 0; i < bvh->totnode; ++i) {
|
2009-11-25 13:40:43 +00:00
|
|
|
node= &bvh->nodes[i];
|
|
|
|
|
|
|
|
if(node->flag & PBVH_Leaf) {
|
|
|
|
if(node->draw_buffers)
|
|
|
|
GPU_free_buffers(node->draw_buffers);
|
|
|
|
if(node->vert_indices)
|
|
|
|
MEM_freeN(node->vert_indices);
|
|
|
|
if(node->face_vert_indices)
|
|
|
|
MEM_freeN(node->face_vert_indices);
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-21 20:10:59 +00:00
|
|
|
if (bvh->deformed) {
|
|
|
|
if (bvh->verts) {
|
|
|
|
/* if pbvh was deformed, new memory was allocated for verts/faces -- free it */
|
|
|
|
|
|
|
|
MEM_freeN(bvh->verts);
|
|
|
|
MEM_freeN(bvh->faces);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
MEM_freeN(bvh->nodes);
|
2009-11-25 13:40:43 +00:00
|
|
|
MEM_freeN(bvh->prim_indices);
|
2009-10-27 19:53:34 +00:00
|
|
|
MEM_freeN(bvh);
|
|
|
|
}
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
static void pbvh_iter_begin(PBVHIter *iter, PBVH *bvh, BLI_pbvh_SearchCallback scb, void *search_data)
|
|
|
|
{
|
|
|
|
iter->bvh= bvh;
|
|
|
|
iter->scb= scb;
|
|
|
|
iter->search_data= search_data;
|
|
|
|
|
|
|
|
iter->stack= iter->stackfixed;
|
|
|
|
iter->stackspace= STACK_FIXED_DEPTH;
|
|
|
|
|
|
|
|
iter->stack[0].node= bvh->nodes;
|
|
|
|
iter->stack[0].revisiting= 0;
|
|
|
|
iter->stacksize= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pbvh_iter_end(PBVHIter *iter)
|
|
|
|
{
|
|
|
|
if(iter->stackspace > STACK_FIXED_DEPTH)
|
|
|
|
MEM_freeN(iter->stack);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pbvh_stack_push(PBVHIter *iter, PBVHNode *node, int revisiting)
|
|
|
|
{
|
|
|
|
if(iter->stacksize == iter->stackspace) {
|
|
|
|
PBVHStack *newstack;
|
|
|
|
|
|
|
|
iter->stackspace *= 2;
|
|
|
|
newstack= MEM_callocN(sizeof(PBVHStack)*iter->stackspace, "PBVHStack");
|
|
|
|
memcpy(newstack, iter->stack, sizeof(PBVHStack)*iter->stacksize);
|
|
|
|
|
|
|
|
if(iter->stackspace > STACK_FIXED_DEPTH)
|
|
|
|
MEM_freeN(iter->stack);
|
|
|
|
iter->stack= newstack;
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
|
|
|
iter->stack[iter->stacksize].node= node;
|
|
|
|
iter->stack[iter->stacksize].revisiting= revisiting;
|
|
|
|
iter->stacksize++;
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
static PBVHNode *pbvh_iter_next(PBVHIter *iter)
|
2009-10-27 19:53:34 +00:00
|
|
|
{
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
PBVHNode *node;
|
|
|
|
int revisiting;
|
|
|
|
|
|
|
|
/* purpose here is to traverse tree, visiting child nodes before their
|
|
|
|
parents, this order is necessary for e.g. computing bounding boxes */
|
|
|
|
|
|
|
|
while(iter->stacksize) {
|
2010-07-14 14:11:03 +00:00
|
|
|
/* pop node */
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
iter->stacksize--;
|
|
|
|
node= iter->stack[iter->stacksize].node;
|
2010-01-10 10:20:44 +00:00
|
|
|
|
2010-01-10 10:50:11 +00:00
|
|
|
/* on a mesh with no faces this can happen
|
|
|
|
* can remove this check if we know meshes have at least 1 face */
|
2010-01-10 10:20:44 +00:00
|
|
|
if(node==NULL)
|
|
|
|
return NULL;
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
revisiting= iter->stack[iter->stacksize].revisiting;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
/* revisiting node already checked */
|
|
|
|
if(revisiting)
|
|
|
|
return node;
|
|
|
|
|
2010-07-14 14:11:03 +00:00
|
|
|
if(iter->scb && !iter->scb(node, iter->search_data))
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
continue; /* don't traverse, outside of search zone */
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
if(node->flag & PBVH_Leaf) {
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
/* immediately hit leaf node */
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* come back later when children are done */
|
|
|
|
pbvh_stack_push(iter, node, 1);
|
|
|
|
|
|
|
|
/* push two child nodes on the stack */
|
|
|
|
pbvh_stack_push(iter, iter->bvh->nodes+node->children_offset+1, 0);
|
|
|
|
pbvh_stack_push(iter, iter->bvh->nodes+node->children_offset, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-07-14 14:11:03 +00:00
|
|
|
static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
|
|
|
|
{
|
|
|
|
PBVHNode *node;
|
|
|
|
|
|
|
|
while(iter->stacksize) {
|
|
|
|
/* pop node */
|
|
|
|
iter->stacksize--;
|
|
|
|
node= iter->stack[iter->stacksize].node;
|
|
|
|
|
|
|
|
/* on a mesh with no faces this can happen
|
|
|
|
* can remove this check if we know meshes have at least 1 face */
|
|
|
|
if(node==NULL) return NULL;
|
|
|
|
|
|
|
|
if(iter->scb && !iter->scb(node, iter->search_data)) continue; /* don't traverse, outside of search zone */
|
|
|
|
|
|
|
|
if(node->flag & PBVH_Leaf) {
|
|
|
|
/* immediately hit leaf node */
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pbvh_stack_push(iter, iter->bvh->nodes+node->children_offset+1, 0);
|
|
|
|
pbvh_stack_push(iter, iter->bvh->nodes+node->children_offset, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
void BLI_pbvh_search_gather(PBVH *bvh,
|
|
|
|
BLI_pbvh_SearchCallback scb, void *search_data,
|
|
|
|
PBVHNode ***r_array, int *r_tot)
|
|
|
|
{
|
|
|
|
PBVHIter iter;
|
|
|
|
PBVHNode **array= NULL, **newarray, *node;
|
|
|
|
int tot= 0, space= 0;
|
|
|
|
|
|
|
|
pbvh_iter_begin(&iter, bvh, scb, search_data);
|
|
|
|
|
|
|
|
while((node=pbvh_iter_next(&iter))) {
|
|
|
|
if(node->flag & PBVH_Leaf) {
|
|
|
|
if(tot == space) {
|
|
|
|
/* resize array if needed */
|
|
|
|
space= (tot == 0)? 32: space*2;
|
|
|
|
newarray= MEM_callocN(sizeof(PBVHNode)*space, "PBVHNodeSearch");
|
|
|
|
|
|
|
|
if(array) {
|
|
|
|
memcpy(newarray, array, sizeof(PBVHNode)*tot);
|
|
|
|
MEM_freeN(array);
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
|
|
|
array= newarray;
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
array[tot]= node;
|
|
|
|
tot++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pbvh_iter_end(&iter);
|
|
|
|
|
2010-01-05 14:26:38 +00:00
|
|
|
if(tot == 0 && array) {
|
|
|
|
MEM_freeN(array);
|
|
|
|
array= NULL;
|
|
|
|
}
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
*r_array= array;
|
|
|
|
*r_tot= tot;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BLI_pbvh_search_callback(PBVH *bvh,
|
|
|
|
BLI_pbvh_SearchCallback scb, void *search_data,
|
|
|
|
BLI_pbvh_HitCallback hcb, void *hit_data)
|
|
|
|
{
|
|
|
|
PBVHIter iter;
|
|
|
|
PBVHNode *node;
|
|
|
|
|
|
|
|
pbvh_iter_begin(&iter, bvh, scb, search_data);
|
|
|
|
|
|
|
|
while((node=pbvh_iter_next(&iter)))
|
2010-07-14 14:11:03 +00:00
|
|
|
if (node->flag & PBVH_Leaf)
|
2009-11-25 13:40:43 +00:00
|
|
|
hcb(node, hit_data);
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
|
|
|
pbvh_iter_end(&iter);
|
|
|
|
}
|
|
|
|
|
2010-07-14 14:11:03 +00:00
|
|
|
typedef struct node_tree {
|
|
|
|
PBVHNode* data;
|
|
|
|
|
|
|
|
struct node_tree* left;
|
|
|
|
struct node_tree* right;
|
|
|
|
} node_tree;
|
|
|
|
|
|
|
|
static void node_tree_insert(node_tree* tree, node_tree* new_node)
|
|
|
|
{
|
|
|
|
if (new_node->data->tmin < tree->data->tmin) {
|
|
|
|
if (tree->left) {
|
|
|
|
node_tree_insert(tree->left, new_node);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
tree->left = new_node;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (tree->right) {
|
|
|
|
node_tree_insert(tree->right, new_node);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
tree->right = new_node;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void traverse_tree(node_tree* tree, BLI_pbvh_HitOccludedCallback hcb, void* hit_data, float* tmin)
|
|
|
|
{
|
|
|
|
if (tree->left) traverse_tree(tree->left, hcb, hit_data, tmin);
|
|
|
|
|
|
|
|
hcb(tree->data, hit_data, tmin);
|
|
|
|
|
|
|
|
if (tree->right) traverse_tree(tree->right, hcb, hit_data, tmin);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_tree(node_tree* tree)
|
|
|
|
{
|
|
|
|
if (tree->left) {
|
|
|
|
free_tree(tree->left);
|
|
|
|
tree->left = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tree->right) {
|
|
|
|
free_tree(tree->right);
|
|
|
|
tree->right = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(tree);
|
|
|
|
}
|
|
|
|
|
|
|
|
float BLI_pbvh_node_get_tmin(PBVHNode* node)
|
|
|
|
{
|
|
|
|
return node->tmin;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BLI_pbvh_search_callback_occluded(PBVH *bvh,
|
|
|
|
BLI_pbvh_SearchCallback scb, void *search_data,
|
|
|
|
BLI_pbvh_HitOccludedCallback hcb, void *hit_data)
|
|
|
|
{
|
|
|
|
PBVHIter iter;
|
|
|
|
PBVHNode *node;
|
|
|
|
node_tree *tree = 0;
|
|
|
|
|
|
|
|
pbvh_iter_begin(&iter, bvh, scb, search_data);
|
|
|
|
|
|
|
|
while((node=pbvh_iter_next_occluded(&iter))) {
|
|
|
|
if(node->flag & PBVH_Leaf) {
|
|
|
|
node_tree* new_node = malloc(sizeof(node_tree));
|
|
|
|
|
|
|
|
new_node->data = node;
|
|
|
|
|
|
|
|
new_node->left = NULL;
|
|
|
|
new_node->right = NULL;
|
|
|
|
|
|
|
|
if (tree) {
|
|
|
|
node_tree_insert(tree, new_node);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
tree = new_node;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pbvh_iter_end(&iter);
|
|
|
|
|
|
|
|
if (tree) {
|
|
|
|
float tmin = FLT_MAX;
|
|
|
|
traverse_tree(tree, hcb, hit_data, &tmin);
|
|
|
|
free_tree(tree);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
static int update_search_cb(PBVHNode *node, void *data_v)
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
{
|
2009-11-06 16:46:35 +00:00
|
|
|
int flag= GET_INT_FROM_POINTER(data_v);
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
if(node->flag & PBVH_Leaf)
|
2009-11-06 16:46:35 +00:00
|
|
|
return (node->flag & flag);
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-11-04 20:36:38 +00:00
|
|
|
static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
int totnode, float (*face_nors)[3])
|
|
|
|
{
|
2009-11-04 20:36:38 +00:00
|
|
|
float (*vnor)[3];
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
int n;
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
if(bvh->grids)
|
|
|
|
return;
|
|
|
|
|
2009-11-04 20:36:38 +00:00
|
|
|
/* could be per node to save some memory, but also means
|
|
|
|
we have to store for each vertex which node it is in */
|
|
|
|
vnor= MEM_callocN(sizeof(float)*3*bvh->totvert, "bvh temp vnors");
|
|
|
|
|
|
|
|
/* subtle assumptions:
|
|
|
|
- We know that for all edited vertices, the nodes with faces
|
2010-03-22 09:30:00 +00:00
|
|
|
adjacent to these vertices have been marked with PBVH_UpdateNormals.
|
2009-11-04 20:36:38 +00:00
|
|
|
This is true because if the vertex is inside the brush radius, the
|
|
|
|
bounding box of it's adjacent faces will be as well.
|
|
|
|
- However this is only true for the vertices that have actually been
|
2010-03-22 09:30:00 +00:00
|
|
|
edited, not for all vertices in the nodes marked for update, so we
|
2009-11-04 20:36:38 +00:00
|
|
|
can only update vertices marked with ME_VERT_PBVH_UPDATE.
|
|
|
|
*/
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
#pragma omp parallel for private(n) schedule(static)
|
|
|
|
for(n = 0; n < totnode; n++) {
|
2009-11-04 20:36:38 +00:00
|
|
|
PBVHNode *node= nodes[n];
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
|
|
|
if((node->flag & PBVH_UpdateNormals)) {
|
2009-11-04 20:36:38 +00:00
|
|
|
int i, j, totface, *faces;
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
faces= node->prim_indices;
|
|
|
|
totface= node->totprim;
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
|
|
|
for(i = 0; i < totface; ++i) {
|
2009-11-04 20:36:38 +00:00
|
|
|
MFace *f= bvh->faces + faces[i];
|
|
|
|
float fn[3];
|
|
|
|
unsigned int *fv = &f->v1;
|
|
|
|
int sides= (f->v4)? 4: 3;
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
|
|
|
if(f->v4)
|
2009-11-11 10:44:46 +00:00
|
|
|
normal_quad_v3(fn, bvh->verts[f->v1].co, bvh->verts[f->v2].co,
|
|
|
|
bvh->verts[f->v3].co, bvh->verts[f->v4].co);
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
else
|
2009-11-11 10:44:46 +00:00
|
|
|
normal_tri_v3(fn, bvh->verts[f->v1].co, bvh->verts[f->v2].co,
|
|
|
|
bvh->verts[f->v3].co);
|
2009-11-04 20:36:38 +00:00
|
|
|
|
|
|
|
for(j = 0; j < sides; ++j) {
|
|
|
|
int v= fv[j];
|
|
|
|
|
|
|
|
if(bvh->verts[v].flag & ME_VERT_PBVH_UPDATE) {
|
|
|
|
/* this seems like it could be very slow but profile
|
|
|
|
does not show this, so just leave it for now? */
|
|
|
|
#pragma omp atomic
|
|
|
|
vnor[v][0] += fn[0];
|
|
|
|
#pragma omp atomic
|
|
|
|
vnor[v][1] += fn[1];
|
|
|
|
#pragma omp atomic
|
|
|
|
vnor[v][2] += fn[2];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(face_nors)
|
2009-11-11 10:44:46 +00:00
|
|
|
copy_v3_v3(face_nors[faces[i]], fn);
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
}
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#pragma omp parallel for private(n) schedule(static)
|
|
|
|
for(n = 0; n < totnode; n++) {
|
2009-11-04 20:36:38 +00:00
|
|
|
PBVHNode *node= nodes[n];
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
2009-11-04 20:36:38 +00:00
|
|
|
if(node->flag & PBVH_UpdateNormals) {
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
int i, *verts, totvert;
|
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
verts= node->vert_indices;
|
|
|
|
totvert= node->uniq_verts;
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
|
|
|
for(i = 0; i < totvert; ++i) {
|
|
|
|
const int v = verts[i];
|
2009-11-04 20:36:38 +00:00
|
|
|
MVert *mvert= &bvh->verts[v];
|
|
|
|
|
|
|
|
if(mvert->flag & ME_VERT_PBVH_UPDATE) {
|
|
|
|
float no[3];
|
|
|
|
|
2009-11-11 10:44:46 +00:00
|
|
|
copy_v3_v3(no, vnor[v]);
|
|
|
|
normalize_v3(no);
|
2009-11-04 20:36:38 +00:00
|
|
|
|
|
|
|
mvert->no[0] = (short)(no[0]*32767.0f);
|
|
|
|
mvert->no[1] = (short)(no[1]*32767.0f);
|
|
|
|
mvert->no[2] = (short)(no[2]*32767.0f);
|
|
|
|
|
|
|
|
mvert->flag &= ~ME_VERT_PBVH_UPDATE;
|
|
|
|
}
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
node->flag &= ~PBVH_UpdateNormals;
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
2009-11-04 20:36:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(vnor);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes,
|
|
|
|
int totnode, int flag)
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
|
|
|
|
/* update BB, redraw flag */
|
|
|
|
#pragma omp parallel for private(n) schedule(static)
|
|
|
|
for(n = 0; n < totnode; n++) {
|
|
|
|
PBVHNode *node= nodes[n];
|
|
|
|
|
|
|
|
if((flag & PBVH_UpdateBB) && (node->flag & PBVH_UpdateBB))
|
|
|
|
/* don't clear flag yet, leave it for flushing later */
|
|
|
|
update_node_vb(bvh, node);
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
if((flag & PBVH_UpdateOriginalBB) && (node->flag & PBVH_UpdateOriginalBB))
|
|
|
|
node->orig_vb= node->vb;
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
if((flag & PBVH_UpdateRedraw) && (node->flag & PBVH_UpdateRedraw))
|
|
|
|
node->flag &= ~PBVH_UpdateRedraw;
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
}
|
2009-10-27 19:53:34 +00:00
|
|
|
|
2010-03-22 17:17:36 +00:00
|
|
|
static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode, int smooth)
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
{
|
|
|
|
PBVHNode *node;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
/* can't be done in parallel with OpenGL */
|
|
|
|
for(n = 0; n < totnode; n++) {
|
|
|
|
node= nodes[n];
|
|
|
|
|
|
|
|
if(node->flag & PBVH_UpdateDrawBuffers) {
|
2009-11-25 13:40:43 +00:00
|
|
|
if(bvh->grids) {
|
|
|
|
GPU_update_grid_buffers(node->draw_buffers,
|
|
|
|
bvh->grids,
|
|
|
|
node->prim_indices,
|
|
|
|
node->totprim,
|
2010-03-22 17:17:36 +00:00
|
|
|
bvh->gridsize,
|
|
|
|
smooth);
|
2009-11-25 13:40:43 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
GPU_update_mesh_buffers(node->draw_buffers,
|
|
|
|
bvh->verts,
|
|
|
|
node->vert_indices,
|
|
|
|
node->uniq_verts +
|
|
|
|
node->face_verts);
|
|
|
|
}
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
|
|
|
node->flag &= ~PBVH_UpdateDrawBuffers;
|
|
|
|
}
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
}
|
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
static int pbvh_flush_bb(PBVH *bvh, PBVHNode *node, int flag)
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
{
|
|
|
|
int update= 0;
|
|
|
|
|
|
|
|
/* difficult to multithread well, we just do single threaded recursive */
|
|
|
|
if(node->flag & PBVH_Leaf) {
|
2009-11-06 16:46:35 +00:00
|
|
|
if(flag & PBVH_UpdateBB) {
|
|
|
|
update |= (node->flag & PBVH_UpdateBB);
|
|
|
|
node->flag &= ~PBVH_UpdateBB;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(flag & PBVH_UpdateOriginalBB) {
|
|
|
|
update |= (node->flag & PBVH_UpdateOriginalBB);
|
|
|
|
node->flag &= ~PBVH_UpdateOriginalBB;
|
|
|
|
}
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
return update;
|
|
|
|
}
|
|
|
|
else {
|
2009-11-06 16:46:35 +00:00
|
|
|
update |= pbvh_flush_bb(bvh, bvh->nodes + node->children_offset, flag);
|
|
|
|
update |= pbvh_flush_bb(bvh, bvh->nodes + node->children_offset + 1, flag);
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
if(update & PBVH_UpdateBB)
|
2009-10-27 19:53:34 +00:00
|
|
|
update_node_vb(bvh, node);
|
2009-11-06 16:46:35 +00:00
|
|
|
if(update & PBVH_UpdateOriginalBB)
|
|
|
|
node->orig_vb= node->vb;
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
return update;
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 20:36:38 +00:00
|
|
|
void BLI_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
|
2009-10-27 19:53:34 +00:00
|
|
|
{
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
PBVHNode **nodes;
|
|
|
|
int totnode;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
BLI_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(flag),
|
|
|
|
&nodes, &totnode);
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
|
|
|
if(flag & PBVH_UpdateNormals)
|
2009-11-04 20:36:38 +00:00
|
|
|
pbvh_update_normals(bvh, nodes, totnode, face_nors);
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
if(flag & (PBVH_UpdateBB|PBVH_UpdateOriginalBB|PBVH_UpdateRedraw))
|
2009-11-04 20:36:38 +00:00
|
|
|
pbvh_update_BB_redraw(bvh, nodes, totnode, flag);
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
if(flag & (PBVH_UpdateBB|PBVH_UpdateOriginalBB))
|
|
|
|
pbvh_flush_bb(bvh, bvh->nodes, flag);
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
|
|
|
|
if(nodes) MEM_freeN(nodes);
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3])
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
{
|
|
|
|
PBVHIter iter;
|
|
|
|
PBVHNode *node;
|
|
|
|
BB bb;
|
|
|
|
|
|
|
|
BB_reset(&bb);
|
|
|
|
|
|
|
|
pbvh_iter_begin(&iter, bvh, NULL, NULL);
|
|
|
|
|
|
|
|
while((node=pbvh_iter_next(&iter)))
|
|
|
|
if(node->flag & PBVH_UpdateRedraw)
|
|
|
|
BB_expand_with_bb(&bb, &node->vb);
|
|
|
|
|
|
|
|
pbvh_iter_end(&iter);
|
|
|
|
|
2009-11-11 10:44:46 +00:00
|
|
|
copy_v3_v3(bb_min, bb.bmin);
|
|
|
|
copy_v3_v3(bb_max, bb.bmax);
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
}
|
|
|
|
|
2009-12-09 13:37:19 +00:00
|
|
|
void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface)
|
2009-11-25 13:40:43 +00:00
|
|
|
{
|
|
|
|
PBVHIter iter;
|
|
|
|
PBVHNode *node;
|
|
|
|
GHashIterator *hiter;
|
|
|
|
GHash *map;
|
|
|
|
void *face, **faces;
|
2010-07-14 14:11:03 +00:00
|
|
|
unsigned i;
|
|
|
|
int tot;
|
2009-11-25 13:40:43 +00:00
|
|
|
|
2010-05-07 07:54:25 +00:00
|
|
|
map = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "pbvh_get_grid_updates gh");
|
2009-11-25 13:40:43 +00:00
|
|
|
|
|
|
|
pbvh_iter_begin(&iter, bvh, NULL, NULL);
|
|
|
|
|
|
|
|
while((node=pbvh_iter_next(&iter))) {
|
|
|
|
if(node->flag & PBVH_UpdateNormals) {
|
|
|
|
for(i = 0; i < node->totprim; ++i) {
|
|
|
|
face= bvh->gridfaces[node->prim_indices[i]];
|
2009-12-09 13:37:19 +00:00
|
|
|
if(!BLI_ghash_lookup(map, face))
|
|
|
|
BLI_ghash_insert(map, face, face);
|
2009-11-25 13:40:43 +00:00
|
|
|
}
|
|
|
|
|
2009-12-09 13:37:19 +00:00
|
|
|
if(clear)
|
|
|
|
node->flag &= ~PBVH_UpdateNormals;
|
2009-11-25 13:40:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pbvh_iter_end(&iter);
|
|
|
|
|
|
|
|
tot= BLI_ghash_size(map);
|
|
|
|
if(tot == 0) {
|
|
|
|
*totface= 0;
|
|
|
|
*gridfaces= NULL;
|
|
|
|
BLI_ghash_free(map, NULL, NULL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
faces= MEM_callocN(sizeof(void*)*tot, "PBVH Grid Faces");
|
|
|
|
|
|
|
|
for(hiter = BLI_ghashIterator_new(map), i = 0;
|
2010-03-22 09:30:00 +00:00
|
|
|
!BLI_ghashIterator_isDone(hiter);
|
|
|
|
BLI_ghashIterator_step(hiter), ++i)
|
2009-11-25 13:40:43 +00:00
|
|
|
faces[i]= BLI_ghashIterator_getKey(hiter);
|
|
|
|
|
2010-02-01 11:36:22 +00:00
|
|
|
BLI_ghashIterator_free(hiter);
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
BLI_ghash_free(map, NULL, NULL);
|
|
|
|
|
|
|
|
*totface= tot;
|
|
|
|
*gridfaces= faces;
|
|
|
|
}
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
/***************************** Node Access ***********************************/
|
|
|
|
|
|
|
|
void BLI_pbvh_node_mark_update(PBVHNode *node)
|
|
|
|
{
|
2009-11-06 16:46:35 +00:00
|
|
|
node->flag |= PBVH_UpdateNormals|PBVH_UpdateBB|PBVH_UpdateOriginalBB|PBVH_UpdateDrawBuffers|PBVH_UpdateRedraw;
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
}
|
|
|
|
|
2009-12-11 16:59:09 +00:00
|
|
|
void BLI_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node, int **vert_indices, MVert **verts)
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
{
|
2009-11-06 16:46:35 +00:00
|
|
|
if(vert_indices) *vert_indices= node->vert_indices;
|
2009-12-11 16:59:09 +00:00
|
|
|
if(verts) *verts= bvh->verts;
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
}
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *totvert)
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
{
|
2009-11-25 13:40:43 +00:00
|
|
|
if(bvh->grids) {
|
2009-12-07 19:11:37 +00:00
|
|
|
if(totvert) *totvert= node->totprim*bvh->gridsize*bvh->gridsize;
|
|
|
|
if(uniquevert) *uniquevert= *totvert;
|
2009-11-25 13:40:43 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-12-07 19:11:37 +00:00
|
|
|
if(totvert) *totvert= node->uniq_verts + node->face_verts;
|
|
|
|
if(uniquevert) *uniquevert= node->uniq_verts;
|
2009-11-25 13:40:43 +00:00
|
|
|
}
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
}
|
|
|
|
|
2009-12-09 13:37:19 +00:00
|
|
|
void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, DMGridData ***griddata, DMGridAdjacency **gridadj)
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
{
|
2009-11-25 13:40:43 +00:00
|
|
|
if(bvh->grids) {
|
|
|
|
if(grid_indices) *grid_indices= node->prim_indices;
|
|
|
|
if(totgrid) *totgrid= node->totprim;
|
|
|
|
if(maxgrid) *maxgrid= bvh->totgrid;
|
|
|
|
if(gridsize) *gridsize= bvh->gridsize;
|
2009-12-09 13:37:19 +00:00
|
|
|
if(griddata) *griddata= bvh->grids;
|
|
|
|
if(gridadj) *gridadj= bvh->gridadj;
|
2009-11-25 13:40:43 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-12-07 19:11:37 +00:00
|
|
|
if(grid_indices) *grid_indices= NULL;
|
|
|
|
if(totgrid) *totgrid= 0;
|
|
|
|
if(maxgrid) *maxgrid= 0;
|
|
|
|
if(gridsize) *gridsize= 0;
|
2009-12-09 13:37:19 +00:00
|
|
|
if(griddata) *griddata= NULL;
|
|
|
|
if(gridadj) *gridadj= NULL;
|
2009-11-25 13:40:43 +00:00
|
|
|
}
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
}
|
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
void BLI_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
|
|
|
|
{
|
2009-11-11 10:44:46 +00:00
|
|
|
copy_v3_v3(bb_min, node->vb.bmin);
|
|
|
|
copy_v3_v3(bb_max, node->vb.bmax);
|
2009-11-06 16:46:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BLI_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
|
|
|
|
{
|
2009-11-11 10:44:46 +00:00
|
|
|
copy_v3_v3(bb_min, node->orig_vb.bmin);
|
|
|
|
copy_v3_v3(bb_max, node->orig_vb.bmax);
|
2009-11-06 16:46:35 +00:00
|
|
|
}
|
|
|
|
|
2010-07-14 14:11:03 +00:00
|
|
|
void BLI_pbvh_node_get_proxies(PBVHNode* node, PBVHProxyNode** proxies, int* proxy_count)
|
|
|
|
{
|
|
|
|
if (node->proxy_count > 0) {
|
|
|
|
if (proxies) *proxies = node->proxies;
|
|
|
|
if (proxy_count) *proxy_count = node->proxy_count;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (proxies) *proxies = 0;
|
|
|
|
if (proxy_count) *proxy_count = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Sculpt: Multithreading & PBVH Changes
* Sculpting, normal update and bounding box code is now multithreaded
using OpenMP.
* Fix a number of update issues: normals on node boundaries, outdated
bounding boxes, partial redraw, .. . There's probably still a few
left, but should be better now.
* Clicking once now does a single paint instead of two (was also
painting on mouse up event).
* Smooth shading now is enabled for the full mesh when the first face
uses it (so it can be tested at least).
Implementation Notes:
* PBVH search can now be done either using a callback or bt gathering the
nodes in an array. The latter makes multithreading with OpenMP easier.
* Normals update code is now inside PBVH, was doing it per node before but
should do all faces first and only then vertices.
* Instead of using search modes + 1 modified flag, now nodes get 4 flags
to indicate what needs to be updated for them, found that this makes it
easier for me to understand the code and fix update bugs.
* PBVHNode is now exposed as an abstract type, I think this makes it more
clear what is happening than having it's data passed as part of callback
functions.
* Active_verts list was replaced by looping over nodes and the vertices
inside them. However the grab brush still uses the active_verts system,
will fix that later.
* Some micro-optimizations, like avoiding a few multiplications/divisions,
using local variables instead of pointers, or looping over fewer vertices
to update the bounding boxes.
2009-11-02 18:47:03 +00:00
|
|
|
/********************************* Raycast ***********************************/
|
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
typedef struct {
|
|
|
|
/* Ray */
|
|
|
|
float start[3];
|
|
|
|
int sign[3];
|
|
|
|
float inv_dir[3];
|
2009-11-06 16:46:35 +00:00
|
|
|
int original;
|
2009-10-27 19:53:34 +00:00
|
|
|
} RaycastData;
|
|
|
|
|
|
|
|
/* Adapted from here: http://www.gamedev.net/community/forums/topic.asp?topic_id=459973 */
|
2009-11-06 16:46:35 +00:00
|
|
|
static int ray_aabb_intersect(PBVHNode *node, void *data_v)
|
2009-10-27 19:53:34 +00:00
|
|
|
{
|
|
|
|
RaycastData *ray = data_v;
|
2010-07-14 14:11:03 +00:00
|
|
|
float bbox[2][3];
|
2009-10-27 19:53:34 +00:00
|
|
|
float tmin, tmax, tymin, tymax, tzmin, tzmax;
|
|
|
|
|
2009-11-06 16:46:35 +00:00
|
|
|
if(ray->original)
|
2010-07-14 14:11:03 +00:00
|
|
|
BLI_pbvh_node_get_original_BB(node, bbox[0], bbox[1]);
|
2009-11-06 16:46:35 +00:00
|
|
|
else
|
2010-07-14 14:11:03 +00:00
|
|
|
BLI_pbvh_node_get_BB(node, bbox[0], bbox[1]);
|
2009-10-27 19:53:34 +00:00
|
|
|
|
|
|
|
tmin = (bbox[ray->sign[0]][0] - ray->start[0]) * ray->inv_dir[0];
|
|
|
|
tmax = (bbox[1-ray->sign[0]][0] - ray->start[0]) * ray->inv_dir[0];
|
|
|
|
|
|
|
|
tymin = (bbox[ray->sign[1]][1] - ray->start[1]) * ray->inv_dir[1];
|
|
|
|
tymax = (bbox[1-ray->sign[1]][1] - ray->start[1]) * ray->inv_dir[1];
|
|
|
|
|
|
|
|
if((tmin > tymax) || (tymin > tmax))
|
|
|
|
return 0;
|
2010-07-14 14:11:03 +00:00
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
if(tymin > tmin)
|
|
|
|
tmin = tymin;
|
2010-07-14 14:11:03 +00:00
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
if(tymax < tmax)
|
|
|
|
tmax = tymax;
|
|
|
|
|
|
|
|
tzmin = (bbox[ray->sign[2]][2] - ray->start[2]) * ray->inv_dir[2];
|
|
|
|
tzmax = (bbox[1-ray->sign[2]][2] - ray->start[2]) * ray->inv_dir[2];
|
|
|
|
|
|
|
|
if((tmin > tzmax) || (tzmin > tmax))
|
|
|
|
return 0;
|
|
|
|
|
2010-07-14 14:11:03 +00:00
|
|
|
if(tzmin > tmin)
|
|
|
|
tmin = tzmin;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
2010-07-14 14:11:03 +00:00
|
|
|
// XXX jwilkins: tmax does not need to be updated since we don't use it
|
|
|
|
// keeping this here for future reference
|
|
|
|
//if(tzmax < tmax) tmax = tzmax;
|
|
|
|
|
|
|
|
node->tmin = tmin;
|
|
|
|
|
|
|
|
return 1;
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
|
2010-07-14 14:11:03 +00:00
|
|
|
void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
|
2010-03-22 09:30:00 +00:00
|
|
|
float ray_start[3], float ray_normal[3], int original)
|
2009-10-27 19:53:34 +00:00
|
|
|
{
|
|
|
|
RaycastData rcd;
|
|
|
|
|
2009-11-11 10:44:46 +00:00
|
|
|
copy_v3_v3(rcd.start, ray_start);
|
2009-10-27 19:53:34 +00:00
|
|
|
rcd.inv_dir[0] = 1.0f / ray_normal[0];
|
|
|
|
rcd.inv_dir[1] = 1.0f / ray_normal[1];
|
|
|
|
rcd.inv_dir[2] = 1.0f / ray_normal[2];
|
|
|
|
rcd.sign[0] = rcd.inv_dir[0] < 0;
|
|
|
|
rcd.sign[1] = rcd.inv_dir[1] < 0;
|
|
|
|
rcd.sign[2] = rcd.inv_dir[2] < 0;
|
2009-11-06 16:46:35 +00:00
|
|
|
rcd.original = original;
|
2009-10-27 19:53:34 +00:00
|
|
|
|
2010-07-14 14:11:03 +00:00
|
|
|
BLI_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
|
2009-10-27 19:53:34 +00:00
|
|
|
}
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
static int ray_face_intersection(float ray_start[3], float ray_normal[3],
|
|
|
|
float *t0, float *t1, float *t2, float *t3,
|
|
|
|
float *fdist)
|
|
|
|
{
|
2010-07-14 14:11:03 +00:00
|
|
|
float dist;
|
|
|
|
|
|
|
|
if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2, &dist, NULL, 0.1f) && dist < *fdist) ||
|
|
|
|
(t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist, NULL, 0.1f) && dist < *fdist))
|
|
|
|
{
|
|
|
|
*fdist = dist;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
2009-11-25 13:40:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
|
|
|
|
float ray_start[3], float ray_normal[3], float *dist)
|
|
|
|
{
|
|
|
|
int hit= 0;
|
|
|
|
|
|
|
|
if(bvh->faces) {
|
|
|
|
MVert *vert = bvh->verts;
|
|
|
|
int *faces= node->prim_indices;
|
|
|
|
int *face_verts= node->face_vert_indices;
|
|
|
|
int totface= node->totprim;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for(i = 0; i < totface; ++i) {
|
|
|
|
MFace *f = bvh->faces + faces[i];
|
|
|
|
|
|
|
|
if(origco) {
|
|
|
|
/* intersect with backuped original coordinates */
|
|
|
|
hit |= ray_face_intersection(ray_start, ray_normal,
|
|
|
|
origco[face_verts[i*4+0]],
|
|
|
|
origco[face_verts[i*4+1]],
|
|
|
|
origco[face_verts[i*4+2]],
|
|
|
|
f->v4? origco[face_verts[i*4+3]]: NULL,
|
|
|
|
dist);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* intersect with current coordinates */
|
|
|
|
hit |= ray_face_intersection(ray_start, ray_normal,
|
|
|
|
vert[f->v1].co,
|
|
|
|
vert[f->v2].co,
|
|
|
|
vert[f->v3].co,
|
|
|
|
f->v4 ? vert[f->v4].co : NULL,
|
|
|
|
dist);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
int totgrid= node->totprim;
|
|
|
|
int gridsize= bvh->gridsize;
|
|
|
|
int i, x, y;
|
|
|
|
|
|
|
|
for(i = 0; i < totgrid; ++i) {
|
|
|
|
DMGridData *grid= bvh->grids[node->prim_indices[i]];
|
2010-05-03 16:06:36 +00:00
|
|
|
if (!grid)
|
|
|
|
continue;
|
2009-11-25 13:40:43 +00:00
|
|
|
|
|
|
|
for(y = 0; y < gridsize-1; ++y) {
|
|
|
|
for(x = 0; x < gridsize-1; ++x) {
|
|
|
|
if(origco) {
|
|
|
|
hit |= ray_face_intersection(ray_start, ray_normal,
|
|
|
|
origco[y*gridsize + x],
|
|
|
|
origco[y*gridsize + x+1],
|
|
|
|
origco[(y+1)*gridsize + x+1],
|
|
|
|
origco[(y+1)*gridsize + x],
|
|
|
|
dist);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
hit |= ray_face_intersection(ray_start, ray_normal,
|
|
|
|
grid[y*gridsize + x].co,
|
|
|
|
grid[y*gridsize + x+1].co,
|
|
|
|
grid[(y+1)*gridsize + x+1].co,
|
|
|
|
grid[(y+1)*gridsize + x].co,
|
|
|
|
dist);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(origco)
|
|
|
|
origco += gridsize*gridsize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return hit;
|
|
|
|
}
|
|
|
|
|
2009-12-11 14:16:17 +00:00
|
|
|
//#include <GL/glew.h>
|
2009-11-25 13:40:43 +00:00
|
|
|
|
2010-10-16 02:40:31 +00:00
|
|
|
void BLI_pbvh_node_draw(PBVHNode *node, void *UNUSED(data))
|
2009-12-11 14:16:17 +00:00
|
|
|
{
|
|
|
|
#if 0
|
2009-11-25 13:40:43 +00:00
|
|
|
/* XXX: Just some quick code to show leaf nodes in different colors */
|
2009-12-11 14:16:17 +00:00
|
|
|
float col[3]; int i;
|
|
|
|
|
|
|
|
if(0) { //is_partial) {
|
2009-11-25 13:40:43 +00:00
|
|
|
col[0] = (rand() / (float)RAND_MAX); col[1] = col[2] = 0.6;
|
|
|
|
}
|
|
|
|
else {
|
2009-12-11 14:16:17 +00:00
|
|
|
srand((long long)node);
|
2009-11-25 13:40:43 +00:00
|
|
|
for(i = 0; i < 3; ++i)
|
|
|
|
col[i] = (rand() / (float)RAND_MAX) * 0.3 + 0.7;
|
|
|
|
}
|
|
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
|
|
|
|
|
2009-12-11 14:16:17 +00:00
|
|
|
glColor3f(1, 0, 0);
|
2009-11-25 13:40:43 +00:00
|
|
|
#endif
|
|
|
|
GPU_draw_buffers(node->draw_buffers);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Adapted from:
|
|
|
|
http://www.gamedev.net/community/forums/topic.asp?topic_id=512123
|
|
|
|
Returns true if the AABB is at least partially within the frustum
|
|
|
|
(ok, not a real frustum), false otherwise.
|
|
|
|
*/
|
|
|
|
int BLI_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data)
|
|
|
|
{
|
|
|
|
float (*planes)[4] = data;
|
|
|
|
int i, axis;
|
|
|
|
float vmin[3], vmax[3], bb_min[3], bb_max[3];
|
|
|
|
|
|
|
|
BLI_pbvh_node_get_BB(node, bb_min, bb_max);
|
|
|
|
|
|
|
|
for(i = 0; i < 4; ++i) {
|
|
|
|
for(axis = 0; axis < 3; ++axis) {
|
|
|
|
if(planes[i][axis] > 0) {
|
|
|
|
vmin[axis] = bb_min[axis];
|
|
|
|
vmax[axis] = bb_max[axis];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vmin[axis] = bb_max[axis];
|
|
|
|
vmax[axis] = bb_min[axis];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(dot_v3v3(planes[i], vmin) + planes[i][3] > 0)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-03-22 17:17:36 +00:00
|
|
|
void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3], int smooth)
|
2009-11-25 13:40:43 +00:00
|
|
|
{
|
2010-03-22 17:17:36 +00:00
|
|
|
PBVHNode **nodes;
|
|
|
|
int totnode;
|
|
|
|
|
|
|
|
BLI_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals|PBVH_UpdateDrawBuffers),
|
|
|
|
&nodes, &totnode);
|
|
|
|
|
|
|
|
pbvh_update_normals(bvh, nodes, totnode, face_nors);
|
|
|
|
pbvh_update_draw_buffers(bvh, nodes, totnode, smooth);
|
|
|
|
|
|
|
|
if(nodes) MEM_freeN(nodes);
|
2009-11-25 13:40:43 +00:00
|
|
|
|
|
|
|
if(planes) {
|
|
|
|
BLI_pbvh_search_callback(bvh, BLI_pbvh_node_planes_contain_AABB,
|
|
|
|
planes, BLI_pbvh_node_draw, NULL);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
BLI_pbvh_search_callback(bvh, NULL, NULL, BLI_pbvh_node_draw, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-02 18:04:31 +00:00
|
|
|
void BLI_pbvh_grids_update(PBVH *bvh, DMGridData **grids, DMGridAdjacency *gridadj, void **gridfaces)
|
|
|
|
{
|
|
|
|
bvh->grids= grids;
|
|
|
|
bvh->gridadj= gridadj;
|
|
|
|
bvh->gridfaces= gridfaces;
|
|
|
|
}
|
|
|
|
|
2010-06-21 20:10:59 +00:00
|
|
|
float (*BLI_pbvh_get_vertCos(PBVH *pbvh))[3]
|
|
|
|
{
|
|
|
|
int a;
|
|
|
|
float (*vertCos)[3]= NULL;
|
|
|
|
|
|
|
|
if (pbvh->verts) {
|
|
|
|
float *co;
|
|
|
|
MVert *mvert= pbvh->verts;
|
|
|
|
|
|
|
|
vertCos= MEM_callocN(3*pbvh->totvert*sizeof(float), "BLI_pbvh_get_vertCoords");
|
|
|
|
co= (float*)vertCos;
|
|
|
|
|
|
|
|
for (a= 0; a<pbvh->totvert; a++, mvert++, co+= 3) {
|
|
|
|
copy_v3_v3(co, mvert->co);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return vertCos;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BLI_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
|
|
|
|
{
|
|
|
|
int a;
|
|
|
|
|
|
|
|
if (!pbvh->deformed) {
|
|
|
|
if (pbvh->verts) {
|
|
|
|
/* if pbvh is not already deformed, verts/faces points to the */
|
|
|
|
/* original data and applying new coords to this arrays would lead to */
|
|
|
|
/* unneeded deformation -- duplicate verts/faces to avoid this */
|
|
|
|
|
|
|
|
pbvh->verts= MEM_dupallocN(pbvh->verts);
|
|
|
|
pbvh->faces= MEM_dupallocN(pbvh->faces);
|
|
|
|
|
|
|
|
pbvh->deformed= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pbvh->verts) {
|
|
|
|
/* copy new verts coords */
|
|
|
|
for (a= 0; a < pbvh->totvert; ++a) {
|
|
|
|
copy_v3_v3(pbvh->verts[a].co, vertCos[a]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* coordinates are new -- normals should also be updated */
|
|
|
|
mesh_calc_normals(pbvh->verts, pbvh->totvert, pbvh->faces, pbvh->totprim, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_pbvh_isDeformed(PBVH *pbvh)
|
|
|
|
{
|
|
|
|
return pbvh->deformed;
|
|
|
|
}
|
2010-07-14 14:11:03 +00:00
|
|
|
/* Proxies */
|
|
|
|
|
|
|
|
PBVHProxyNode* BLI_pbvh_node_add_proxy(PBVH* bvh, PBVHNode* node)
|
|
|
|
{
|
|
|
|
int index, totverts;
|
|
|
|
|
|
|
|
#pragma omp critical
|
|
|
|
{
|
|
|
|
|
|
|
|
index = node->proxy_count;
|
|
|
|
|
|
|
|
node->proxy_count++;
|
|
|
|
|
|
|
|
if (node->proxies)
|
|
|
|
node->proxies= MEM_reallocN(node->proxies, node->proxy_count*sizeof(PBVHProxyNode));
|
|
|
|
else
|
|
|
|
node->proxies= MEM_mallocN(sizeof(PBVHProxyNode), "PBVHNodeProxy");
|
|
|
|
|
|
|
|
if (bvh->grids)
|
|
|
|
totverts = node->totprim*bvh->gridsize*bvh->gridsize;
|
|
|
|
else
|
|
|
|
totverts = node->uniq_verts;
|
|
|
|
|
|
|
|
node->proxies[index].co= MEM_callocN(sizeof(float[3])*totverts, "PBVHNodeProxy.co");
|
|
|
|
}
|
|
|
|
|
|
|
|
return node->proxies + index;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BLI_pbvh_node_free_proxies(PBVHNode* node)
|
|
|
|
{
|
|
|
|
#pragma omp critical
|
|
|
|
{
|
|
|
|
int p;
|
|
|
|
|
|
|
|
for (p= 0; p < node->proxy_count; p++) {
|
|
|
|
MEM_freeN(node->proxies[p].co);
|
|
|
|
node->proxies[p].co= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(node->proxies);
|
|
|
|
node->proxies = 0;
|
|
|
|
|
|
|
|
node->proxy_count= 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BLI_pbvh_gather_proxies(PBVH* pbvh, PBVHNode*** r_array, int* r_tot)
|
|
|
|
{
|
|
|
|
PBVHNode **array= NULL, **newarray, *node;
|
|
|
|
int tot= 0, space= 0;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
for (n= 0; n < pbvh->totnode; n++) {
|
|
|
|
node = pbvh->nodes + n;
|
|
|
|
|
|
|
|
if(node->proxy_count > 0) {
|
|
|
|
if(tot == space) {
|
|
|
|
/* resize array if needed */
|
|
|
|
space= (tot == 0)? 32: space*2;
|
|
|
|
newarray= MEM_callocN(sizeof(PBVHNode)*space, "BLI_pbvh_gather_proxies");
|
|
|
|
|
|
|
|
if (array) {
|
|
|
|
memcpy(newarray, array, sizeof(PBVHNode)*tot);
|
|
|
|
MEM_freeN(array);
|
|
|
|
}
|
|
|
|
|
|
|
|
array= newarray;
|
|
|
|
}
|
|
|
|
|
|
|
|
array[tot]= node;
|
|
|
|
tot++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(tot == 0 && array) {
|
|
|
|
MEM_freeN(array);
|
|
|
|
array= NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*r_array= array;
|
|
|
|
*r_tot= tot;
|
|
|
|
}
|