Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Susano Pinto <andresusanopinto@gmail.com>2008-07-22 15:50:50 +0400
committerAndre Susano Pinto <andresusanopinto@gmail.com>2008-07-22 15:50:50 +0400
commit06f67dd53178d3729f9b30d018d1a0715287b825 (patch)
treee8c7b3f756024306a1564c1e5bd8a64447eea6c2
parent3c8b695f726f1ee532219772c234e8e75436f981 (diff)
*BVHTreeFromMesh api changed.. it now stores all information like defaults callbacks to raycast and nearest surface (just to make it easier to use)
*Fixed button size of "Above surface"
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h38
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c145
-rw-r--r--source/blender/src/buttons_editing.c4
3 files changed, 114 insertions, 73 deletions
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index 296bbbaf886..f84b8fb6ec4 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -61,11 +61,46 @@ void space_transform_invert(const SpaceTransform *data, float *co);
void space_transform_apply_normal (const SpaceTransform *data, float *co);
void space_transform_invert_normal(const SpaceTransform *data, float *co);
+/* BVH from mesh */
+#include "BLI_kdopbvh.h"
+
+struct DerivedMesh;
+struct MVert;
+struct MFace;
+
+//struct that kepts basic information about a BVHTree build from a mesh
+typedef struct BVHTreeFromMesh
+{
+ struct BVHTree *tree;
+
+ //Callbacks
+ BVHTree_NearestPointCallback nearest_callback;
+ BVHTree_RayCastCallback raycast_callback;
+
+ //Mesh represented on this BVH
+ struct DerivedMesh *mesh;
+ struct MVert *vert;
+ struct MFace *face;
+
+ //radius for sphere cast
+ float sphere_radius;
+
+} BVHTreeFromMesh;
+
+// Builds a bvh tree where nodes are the vertexs of the given mesh. And configures BVHMesh if one given.
+struct BVHTree* bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
+
+// Builds a bvh tree where nodes are the faces of the given mesh. And configures BVHMesh if one is given.
+struct BVHTree* bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
+
+
+
/* Shrinkwrap stuff */
struct Object;
struct DerivedMesh;
struct ShrinkwrapModifierData;
+struct BVHTree;
@@ -75,6 +110,9 @@ typedef struct ShrinkwrapCalcData
struct Object *ob; //object we are applying shrinkwrap to
struct DerivedMesh *original; //mesh before shrinkwrap (TODO clean this variable.. we don't really need it)
+ struct BVHTree *original_tree; //BVHTree build with the original mesh (to be used on kept volume)
+ struct BVHMeshCallbackUserdata *callback;
+
struct DerivedMesh *final; //initially a copy of original mesh.. mesh thats going to be shrinkwrapped
struct DerivedMesh *target; //mesh we are shrinking to
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 0d085450bde..648071b2c9f 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -104,7 +104,7 @@ DerivedMesh *object_get_derived_final(Object *ob, CustomDataMask dataMask)
else
return mesh_get_derived_final(ob, dataMask);
}
-
+
/* ray - triangle */
#define ISECT_EPSILON 1e-6
static float ray_tri_intersection(const BVHTreeRay *ray, const float m_dist, const float *v0, const float *v1, const float *v2)
@@ -167,39 +167,25 @@ void space_transform_invert_normal(const SpaceTransform *data, float *no)
/*
- * BVH tree from mesh vertices
+ * BVH Tree from Mesh
*/
-typedef struct BVHMeshCallbackUserdata
-{
- //Mesh represented on this BVH
- DerivedMesh *mesh;
- MVert *vert;
- MFace *face;
-
- //radius for sphere cast
- float sphere_radius;
-
-} BVHMeshCallbackUserdata;
-
-
-static void bvhtree_meshcallbackdata_init(BVHMeshCallbackUserdata *data, DerivedMesh *mesh, float cast_radius)
-{
- data->mesh = mesh;
- data->vert = mesh->getVertDataArray(mesh, CD_MVERT);
- data->face = mesh->getFaceDataArray(mesh, CD_MFACE);
- data->sphere_radius = cast_radius;
-}
+//callbacks
+static void mesh_faces_nearest_point(void *userdata, int index, const float *co, BVHTreeNearest *nearest);
+static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit);
/*
* Builds a bvh tree.. where nodes are the vertexs of the given mesh
*/
-static BVHTree* bvhtree_from_mesh_verts(DerivedMesh *mesh, float epsilon, int tree_type, int axis)
+BVHTree* bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis)
{
int i;
int numVerts= mesh->getNumVerts(mesh);
MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
BVHTree *tree = NULL;
+ if(data)
+ memset(data, 0, sizeof(*data));
+
if(vert == NULL)
{
printf("bvhtree cant be build: cant get a vertex array");
@@ -213,6 +199,19 @@ static BVHTree* bvhtree_from_mesh_verts(DerivedMesh *mesh, float epsilon, int tr
BLI_bvhtree_insert(tree, i, vert[i].co, 1);
BLI_bvhtree_balance(tree);
+
+ if(data)
+ {
+ data->tree = tree;
+ data->nearest_callback = NULL;
+ data->raycast_callback = NULL;
+
+ data->mesh = mesh;
+ data->vert = mesh->getVertDataArray(mesh, CD_MVERT);
+ data->face = mesh->getFaceDataArray(mesh, CD_MFACE);
+
+ data->sphere_radius = epsilon;
+ }
}
return tree;
@@ -221,7 +220,7 @@ static BVHTree* bvhtree_from_mesh_verts(DerivedMesh *mesh, float epsilon, int tr
/*
* Builds a bvh tree.. where nodes are the faces of the given mesh.
*/
-static BVHTree* bvhtree_from_mesh_faces(DerivedMesh *mesh, float epsilon, int tree_type, int axis)
+BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis)
{
int i;
int numFaces= mesh->getNumFaces(mesh);
@@ -229,6 +228,9 @@ static BVHTree* bvhtree_from_mesh_faces(DerivedMesh *mesh, float epsilon, int tr
MFace *face = mesh->getFaceDataArray(mesh, CD_MFACE);
BVHTree *tree = NULL;
+ if(data)
+ memset(data, 0, sizeof(*data));
+
if(vert == NULL && face == NULL)
{
printf("bvhtree cant be build: cant get a vertex/face array");
@@ -251,6 +253,19 @@ static BVHTree* bvhtree_from_mesh_faces(DerivedMesh *mesh, float epsilon, int tr
BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3);
}
BLI_bvhtree_balance(tree);
+
+ if(data)
+ {
+ data->tree = tree;
+ data->nearest_callback = mesh_faces_nearest_point;
+ data->raycast_callback = mesh_faces_spherecast;
+
+ data->mesh = mesh;
+ data->vert = mesh->getVertDataArray(mesh, CD_MVERT);
+ data->face = mesh->getFaceDataArray(mesh, CD_MFACE);
+
+ data->sphere_radius = epsilon;
+ }
}
return tree;
@@ -262,7 +277,7 @@ static BVHTree* bvhtree_from_mesh_faces(DerivedMesh *mesh, float epsilon, int tr
*/
static void mesh_faces_nearest_point(void *userdata, int index, const float *co, BVHTreeNearest *nearest)
{
- const BVHMeshCallbackUserdata *data = (BVHMeshCallbackUserdata*) userdata;
+ const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata;
MVert *vert = data->vert;
MFace *face = data->face + index;
@@ -300,7 +315,7 @@ static void mesh_faces_nearest_point(void *userdata, int index, const float *co,
*/
static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
- const BVHMeshCallbackUserdata *data = (BVHMeshCallbackUserdata*) userdata;
+ const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata;
MVert *vert = data->vert;
MFace *face = data->face + index;
@@ -1264,18 +1279,17 @@ void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
int vgroup = get_named_vertexgroup_num(calc->ob, calc->smd->vgroup_name);
float tmp_co[3];
- BVHTree *tree = NULL;
+ BVHTreeFromMesh treeData;
BVHTreeNearest nearest;
int numVerts;
MVert *vert = NULL;
MDeformVert *dvert = NULL;
- BENCH_VAR(query);
- BENCH(tree = bvhtree_from_mesh_verts(calc->target, 0.0, 2, 6));
- if(tree == NULL) return OUT_OF_MEMORY();
+ bvhtree_from_mesh_verts(&treeData, calc->target, 0.0, 2, 6);
+ if(treeData.tree == NULL) return OUT_OF_MEMORY();
//Setup nearest
nearest.index = -1;
@@ -1287,7 +1301,6 @@ void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
vert = calc->final->getVertDataArray(calc->final, CD_MVERT);
dvert = calc->final->getVertDataArray(calc->final, CD_MDEFORMVERT);
- BENCH_BEGIN(query);
for(i=0; i<numVerts; i++)
{
int index;
@@ -1303,7 +1316,7 @@ void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
}
else nearest.dist = FLT_MAX;
- index = BLI_bvhtree_find_nearest(tree, tmp_co, &nearest, NULL, NULL);
+ index = BLI_bvhtree_find_nearest(treeData.tree, tmp_co, &nearest, treeData.nearest_callback, &treeData);
if(index != -1)
{
@@ -1315,10 +1328,8 @@ void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
VecLerpf(vert[i].co, vert[i].co, tmp_co, weight); //linear interpolation
}
}
- BENCH_END(query);
- BENCH_REPORT(query);
- BLI_bvhtree_free(tree);
+ BLI_bvhtree_free(treeData.tree);
}
/*
@@ -1419,7 +1430,6 @@ void shrinkwrap_calc_normal_projection_raytree(ShrinkwrapCalcData *calc)
}
*/
-
/*
* This function raycast a single vertex and updates the hit if the "hit" is considered valid.
* Returns TRUE if "hit" was updated.
@@ -1428,7 +1438,7 @@ void shrinkwrap_calc_normal_projection_raytree(ShrinkwrapCalcData *calc)
* MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE (front faces hits are ignored)
* MOD_SHRINKWRAP_CULL_TARGET_BACKFACE (back faces hits are ignored)
*/
-static int normal_projection_project_vertex(char options, const float *vert, const float *dir, const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, BVHMeshCallbackUserdata *userdata)
+static int normal_projection_project_vertex(char options, const float *vert, const float *dir, const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
{
float tmp_co[3], tmp_no[3];
const float *co, *no;
@@ -1490,19 +1500,16 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
char use_normal = calc->smd->shrinkOpts;
//setup raytracing
- BVHTree *tree = NULL;
+ BVHTreeFromMesh treeData;
BVHTreeRayHit hit;
- BVHMeshCallbackUserdata userdata;
- BVHTree_RayCastCallback callback = NULL;
+/*
//cutTree
DerivedMesh * limit_mesh = NULL;
- BVHTree *limit_tree = NULL;
- BVHMeshCallbackUserdata limit_userdata;
- BVHTree_RayCastCallback limit_callback = NULL;
+ BVHTreeFromMesh limitData;
SpaceTransform local2cut;
-
+*/
int numVerts;
MVert *vert = NULL;
@@ -1511,26 +1518,22 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
if( (use_normal & (MOD_SHRINKWRAP_ALLOW_INVERTED_NORMAL | MOD_SHRINKWRAP_ALLOW_DEFAULT_NORMAL)) == 0)
return; //Nothing todo
- BENCH(tree = bvhtree_from_mesh_faces(calc->target, calc->keptDist, 4, 6));
- if(tree == NULL) return OUT_OF_MEMORY();
- bvhtree_meshcallbackdata_init(&userdata, calc->target, calc->keptDist);
- callback = mesh_faces_spherecast;
+ bvhtree_from_mesh_faces(&treeData, calc->target, calc->keptDist, 4, 6);
+ if(treeData.tree == NULL) return OUT_OF_MEMORY();
+/*
if(calc->smd->cutPlane)
{
+ space_transform_setup( &local2cut, calc->ob, calc->smd->cutPlane);
+
//TODO currently we need a copy in case object_get_derived_final returns an emDM that does not defines getVertArray or getFace array
limit_mesh = CDDM_copy( object_get_derived_final(calc->smd->cutPlane, CD_MASK_BAREMESH) );
if(limit_mesh)
- {
- BENCH(limit_tree = bvhtree_from_mesh_faces(limit_mesh, 0.0, 4, 6));
- bvhtree_meshcallbackdata_init(&limit_userdata, limit_mesh, 0.0);
- limit_callback = mesh_faces_spherecast;
-
- space_transform_setup( &local2cut, calc->ob, calc->smd->cutPlane);
- }
- else printf("CutPlane finalDerived mesh is null\n");
+ bvhtree_from_mesh_faces(&limitData, limit_mesh, 0.0, 4, 6);
+ else
+ printf("CutPlane finalDerived mesh is null\n");
}
-
+*/
//Project each vertex along normal
numVerts= calc->final->getNumVerts(calc->final);
@@ -1561,7 +1564,7 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
normal_projection_project_vertex(0, tmp_co, tmp_no, &local2cut, limit_tree, &hit, limit_callback, &limit_userdata);
*/
- if(normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, tmp_no, &calc->local2target, tree, &hit, callback, &userdata))
+ if(normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, tmp_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData))
moved = TRUE;
}
@@ -1574,27 +1577,29 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
if(limit_tree)
normal_projection_project_vertex(0, tmp_co, inv_no, &local2cut, limit_tree, &hit, limit_callback, &limit_userdata);
*/
- if(normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, inv_no, &calc->local2target, tree, &hit, callback, &userdata))
+ if(normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, inv_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData))
moved = TRUE;
}
if(hit.index != -1)
{
- VecLerpf(vert[i].co, vert[i].co, hit.co, weight); //linear interpolation
+ VecLerpf(vert[i].co, vert[i].co, hit.co, weight);
if(moved && calc->moved)
bitset_set(calc->moved, i);
}
}
- BLI_bvhtree_free(tree);
+ BLI_bvhtree_free(treeData.tree);
- if(limit_tree)
- BLI_bvhtree_free(limit_tree);
+/*
+ if(limitData.tree)
+ BLI_bvhtree_free(limitData.tree);
if(limit_mesh)
limit_mesh->release(limit_mesh);
+*/
}
/*
@@ -1609,9 +1614,8 @@ void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
int vgroup = get_named_vertexgroup_num(calc->ob, calc->smd->vgroup_name);
float tmp_co[3];
- BVHTree *tree = NULL;
- BVHTreeNearest nearest;
- BVHMeshCallbackUserdata userdata;
+ BVHTreeFromMesh treeData;
+ BVHTreeNearest nearest;
int numVerts;
MVert *vert = NULL;
@@ -1619,9 +1623,8 @@ void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
//Create a bvh-tree of the given target
- BENCH( tree = bvhtree_from_mesh_faces(calc->target, 0.0, 2, 6) );
- if(tree == NULL) return OUT_OF_MEMORY();
- bvhtree_meshcallbackdata_init(&userdata, calc->target, 0.0);
+ bvhtree_from_mesh_faces( &treeData, calc->target, 0.0, 2, 6);
+ if(treeData.tree == NULL) return OUT_OF_MEMORY();
//Setup nearest
nearest.index = -1;
@@ -1648,7 +1651,7 @@ void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
}
else nearest.dist = FLT_MAX;
- index = BLI_bvhtree_find_nearest(tree, tmp_co, &nearest, mesh_faces_nearest_point, &userdata);
+ index = BLI_bvhtree_find_nearest(treeData.tree, tmp_co, &nearest, treeData.nearest_callback, &treeData);
if(index != -1)
{
@@ -1666,6 +1669,6 @@ void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
}
}
- BLI_bvhtree_free(tree);
+ BLI_bvhtree_free(treeData.tree);
}
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 404da946a5a..235463d5a75 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -2548,10 +2548,10 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
uiDefButBitS(block, TOG, MOD_SHRINKWRAP_CULL_TARGET_BACKFACE, B_MODIFIER_RECALC, "Cull backfaces", lx+buttonWidth/2,cy,buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Controls whether a vertex can be projected to a back face on target");
uiDefButF(block, NUM, B_MODIFIER_RECALC, "Merge Dist:", lx,(cy-=19),buttonWidth,19, &smd->mergeDist, 0.0f, 0.01f, 0.01f, 0.01f, "Specify merge distance");
- uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Cut: ", lx, (cy-=19), buttonWidth,19, &smd->cutPlane, "Target to project points that didn't got projected over target");
+ uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob2: ", lx, (cy-=19), buttonWidth,19, &smd->cutPlane, "Target to project points that didn't got projected over target");
}
else if (smd->shrinkType == MOD_SHRINKWRAP_NEAREST_SURFACE){
- uiDefButBitS(block, TOG, MOD_SHRINKWRAP_KEPT_ABOVE_SURFACE, B_MODIFIER_RECALC, "Above surface", lx,(cy-=19),buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Vertices are kept on the front side of faces");
+ uiDefButBitS(block, TOG, MOD_SHRINKWRAP_KEPT_ABOVE_SURFACE, B_MODIFIER_RECALC, "Above surface", lx,(cy-=19),buttonWidth,19, &smd->shrinkOpts, 0, 0, 0, 0, "Vertices are kept on the front side of faces");
}
but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &smd->vgroup_name, 0, 31, 0, 0, "Vertex Group name");