Fixed some compile erros under msvc (thanks lguillaume)

Fixed object dependency (thanks ZanQdo for pointing it out)
Make some code cleaner
(preparing for adding bvh trees on nearest surface)
This commit is contained in:
Andre Susano Pinto
2008-05-26 21:57:53 +00:00
parent ad3f4c89aa
commit 4383743ace
4 changed files with 151 additions and 88 deletions

View File

@@ -7049,7 +7049,7 @@ static void shrinkwrapModifier_updateDepgraph(ModifierData *md, DagForest *fores
if (smd->target) {
DagNode *curNode = dag_get_node(forest, smd->target);
dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA,
"Shrinkwrap Modifier");
}
}

View File

@@ -31,8 +31,6 @@
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <assert.h>
//TODO: its late and I don't fill like adding ifs() printfs (I'll remove them on end)
#include "DNA_object_types.h"
#include "DNA_modifier_types.h"
@@ -108,12 +106,73 @@ static float vertexgroup_get_weight(MDeformVert *dvert, int index, int vgroup)
return 1.0;
}
/*
* BVH tree from mesh vertices
*/
static BVHTree* bvhtree_from_mesh_verts(DerivedMesh *mesh)
{
int i;
int numVerts= mesh->getNumVerts(mesh);
MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
BVHTree *tree = BLI_bvhtree_new(numVerts, 0, 2, 6);
if(tree != NULL)
{
for(i = 0; i < numVerts; i++)
BLI_bvhtree_insert(tree, i, vert[i].co, 1);
BLI_bvhtree_balance(tree);
}
return tree;
}
static BVHTree* bvhtree_from_mesh_tri(DerivedMesh *mesh)
{
int i;
int numFaces= mesh->getNumFaces(mesh), totFaces;
MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
MFace *face = mesh->getFaceDataArray(mesh, CD_MFACE);
BVHTree *tree= NULL;
/* Count needed faces */
for(totFaces=numFaces, i=0; i<numFaces; i++)
if(face[i].v4) totFaces++;
/* Create a bvh-tree of the given target */
tree = BLI_bvhtree_new(totFaces, 0, 2, 6);
if(tree != NULL)
{
for(i = 0; i < numFaces; i++)
{
float co[4][3];
VECCOPY(co[0], vert[ face[i].v1 ].co);
VECCOPY(co[1], vert[ face[i].v2 ].co);
VECCOPY(co[2], vert[ face[i].v3 ].co);
if(face[i].v4)
VECCOPY(co[3], vert[ face[i].v4 ].co);
BLI_bvhtree_insert(tree, 2*i, co[0], 3);
if(face[i].v4)
BLI_bvhtree_insert(tree, 2*i+1, co[1], 3);
}
BLI_bvhtree_balance(tree);
}
return tree;
}
/*
* Raytree from mesh
*/
static MVert *raytree_from_mesh_verts = NULL;
static MFace *raytree_from_mesh_faces = NULL;
//static float raytree_from_mesh_start[3] = { 0.0f, 0.0f, 0.0f };
static int raytree_check_always(Isect *is, int ob, RayFace *face)
{
return TRUE;
@@ -125,17 +184,16 @@ static void raytree_from_mesh_get_coords(RayFace *face, float **v1, float **v2,
if(face == (RayFace*)(-1))
{
*v1 = NULL; //raytree_from_mesh_start;
*v2 = NULL; //raytree_from_mesh_start;
*v3 = NULL; //raytree_from_mesh_start;
*v1 = NULL;
*v2 = NULL;
*v3 = NULL;
*v4 = NULL;
return;
}
//Nasty quad splitting
if(((int)face) & 1) //we want the 2 triangle of the quad
if(((int)face) & 1) // we want the 2 triangle of the quad
{
assert(mface->v4);
*v1= raytree_from_mesh_verts[mface->v1].co;
*v2= raytree_from_mesh_verts[mface->v4].co;
*v3= raytree_from_mesh_verts[mface->v3].co;
@@ -189,8 +247,8 @@ static RayTree* raytree_create_from_mesh(DerivedMesh *mesh)
{
RE_ray_tree_add_face(tree, 0, (RayFace*)(i*2) );
//Theres some nasty thing with non-coplanar quads (that I can't find the issue)
//so we split quads (an odd numbered face represents the second triangle of the quad)
//Theres some nasty thing with non-coplanar quads (that I can't find the issue)
//so we split quads (an odd numbered face represents the second triangle of the quad)
if(face[i-1].v4)
RE_ray_tree_add_face(tree, 0, (RayFace*)(i*2+1));
}
@@ -213,10 +271,10 @@ static void free_raytree_from_mesh(RayTree *tree)
*/
static float raytree_cast_ray(RayTree *tree, const float *coord, const float *direction)
{
Isect isec = {};
Isect isec;
//Setup intersection
isec.mode = RE_RAY_MIRROR; //We want closest intersection
/* Setup intersection */
isec.mode = RE_RAY_MIRROR; /* We want closest intersection */
isec.lay = -1;
isec.face_last = NULL;
isec.faceorig = (RayFace*)(-1);
@@ -304,7 +362,7 @@ static float choose_nearest(const float v0[2], const float v1[2], const float po
* returns that tri must be right-handed
* Returns square distance
*/
static float closest_point_in_tri2D(const float point[2], const float tri[3][2], float closest[2])
static float closest_point_in_tri2D(const float point[2], /*const*/ float tri[3][2], float closest[2])
{
float edge_di[2];
float v_point[2];
@@ -540,9 +598,7 @@ static void bruteforce_shrinkwrap_calc_nearest_vertex(DerivedMesh *target, float
for (i = 0; i < numVerts; i++)
{
float diff[3], sdist;
VECSUB(diff, orig_co, vert[i].co);
sdist = INPR(diff, diff);
float sdist = squared_dist( orig_co, vert[i].co);
if(sdist < minDist)
{
@@ -707,8 +763,8 @@ static void shrinkwrap_removeUnused(ShrinkwrapCalcData *calc)
DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
{
ShrinkwrapCalcData calc = {};
ShrinkwrapCalcData calc;
memset(&calc, 0, sizeof(calc));
//Init Shrinkwrap calc data
calc.smd = smd;
@@ -752,6 +808,7 @@ DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, Deri
switch(smd->shrinkType)
{
case MOD_SHRINKWRAP_NEAREST_SURFACE:
// BENCH(shrinkwrap_calc_nearest_surface_point(&calc));
BENCH(shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_nearest_surface_point));
break;
@@ -791,62 +848,26 @@ void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
{
int i;
int vgroup = get_named_vertexgroup_num(calc->ob, calc->smd->vgroup_name);
/*
KDTree* target = NULL;
KDTreeNearest knearest;
*/
float tmp_co[3];
BVHTree *tree = NULL;
BVHTreeNearest nearest;
BVHTreeNearest nearest = {};
BENCH_VAR(build);
BENCH_VAR(query);
int numVerts;
MVert *vert = NULL, *tvert = NULL;
MVert *vert = NULL;
MDeformVert *dvert = NULL;
numVerts= calc->target->getNumVerts(calc->target);
vert = tvert = calc->target->getVertDataArray(calc->target, CD_MVERT);
BENCH_RESET(build);
BENCH_BEGIN(build);
//Create a bvh-tree of the given target
tree = BLI_bvhtree_new(numVerts, 0, 2, 6);
BENCH(tree = bvhtree_from_mesh_verts(calc->target));
if(tree == NULL) return OUT_OF_MEMORY();
for(i = 0; i < numVerts; i++)
BLI_bvhtree_insert(tree, i, vert[i].co, 1);
BLI_bvhtree_balance(tree);
nearest.index = -1;
nearest.dist = FLT_MAX;
BENCH_END(build);
BENCH_REPORT(build);
/*
//Generate kd-tree with target vertexs
BENCH_RESET(build);
BENCH_BEGIN(build);
target = BLI_kdtree_new(numVerts);
if(target == NULL) return OUT_OF_MEMORY();
for(i = 0; i < numVerts; i++)
BLI_kdtree_insert(target, 0, vert[i].co, NULL);
BLI_kdtree_balance(target);
BENCH_END(build);
BENCH_REPORT(build);
*/
//Find the nearest vertex
numVerts= calc->final->getNumVerts(calc->final);
vert = calc->final->getVertDataArray(calc->final, CD_MVERT);
@@ -863,47 +884,25 @@ void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
if(nearest.index != -1)
{
nearest.dist = squared_dist(tmp_co, tvert[nearest.index].co);
nearest.dist = squared_dist(tmp_co, nearest.nearest);
}
else nearest.dist = FLT_MAX;
index = BLI_bvhtree_find_nearest(tree, tmp_co, &nearest);
/*
t = BLI_kdtree_find_nearest(target, tmp_co, 0, &knearest);
if(VecLenf(knearest.co, tvert[index].co) > 1e-5)
{
printf("Nearest failed: {%f,%f,%f} - ", knearest.co[0], knearest.co[1], knearest.co[2]);
printf("{%f,%f,%f}\n", tvert[index].co[0], tvert[index].co[1], tvert[index].co[2]);
}
*/
if(index != -1)
{
float dist;
VecMat4MulVecfl(tmp_co, calc->target2local, tvert[index].co);
VecMat4MulVecfl(tmp_co, calc->target2local, nearest.nearest);
dist = VecLenf(vert[i].co, tmp_co);
if(dist > 1e-5) weight *= (dist - calc->keptDist)/dist;
VecLerpf(vert[i].co, vert[i].co, tmp_co, weight); //linear interpolation
}
/* if(t != -1)
{
float dist;
VecMat4MulVecfl(knearest.co, calc->target2local, knearest.co);
dist = VecLenf(vert[i].co, knearest.co);
if(dist > 1e-5) weight *= (dist - calc->keptDist)/dist;
VecLerpf(vert[i].co, vert[i].co, knearest.co, weight); //linear interpolation
}
*/
}
BENCH_END(query);
BENCH_REPORT(query);
// BLI_kdtree_free(target);
BLI_bvhtree_free(tree);
}
@@ -1000,4 +999,66 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
free_raytree_from_mesh(target);
}
/*
* Shrinkwrap moving vertexs to the nearest surface point on the target
*
* it builds a BVHTree from the target mesh and then performs a
* NN matchs for each vertex
*/
void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
{
int i;
int vgroup = get_named_vertexgroup_num(calc->ob, calc->smd->vgroup_name);
float tmp_co[3];
BVHTree *tree = NULL;
BVHTreeNearest nearest = {};
int numVerts;
MVert *vert = NULL;
MDeformVert *dvert = NULL;
//Create a bvh-tree of the given target
tree = bvhtree_from_mesh_tri(calc->target);
if(tree == NULL) return OUT_OF_MEMORY();
nearest.index = -1;
nearest.dist = FLT_MAX;
//Find the nearest vertex
numVerts= calc->final->getNumVerts(calc->final);
vert = calc->final->getVertDataArray(calc->final, CD_MVERT);
dvert = calc->final->getVertDataArray(calc->final, CD_MDEFORMVERT);
for(i=0; i<numVerts; i++)
{
int index;
float weight = vertexgroup_get_weight(dvert, i, vgroup);
if(weight == 0.0f) continue;
VecMat4MulVecfl(tmp_co, calc->local2target, vert[i].co);
if(nearest.index != -1)
{
nearest.dist = squared_dist(tmp_co, nearest.nearest);
}
else nearest.dist = FLT_MAX;
index = BLI_bvhtree_find_nearest(tree, tmp_co, &nearest);
if(index != -1)
{
float dist;
VecMat4MulVecfl(tmp_co, calc->target2local, nearest.nearest);
dist = VecLenf(vert[i].co, tmp_co);
if(dist > 1e-5) weight *= (dist - calc->keptDist)/dist;
VecLerpf(vert[i].co, vert[i].co, tmp_co, weight); //linear interpolation
}
}
BLI_bvhtree_free(tree);
}

View File

@@ -42,8 +42,9 @@ typedef struct BVHTreeOverlap {
typedef struct BVHTreeNearest
{
int index; /* the index of the nearest found (untouched if none is found within a dist radius from the given coordinates) */
float dist; /* squared distance to search arround */
int index; /* the index of the nearest found (untouched if none is found within a dist radius from the given coordinates) */
float nearest[3]; /* nearest coordinates (untouched it none is found within a dist radius from the given coordinates) */
float dist; /* squared distance to search arround */
} BVHTreeNearest;
BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis);

View File

@@ -7,7 +7,7 @@
* 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. The Blender
* Foundation also sells licenses for use in proprietary software under
* Foundation also sells licenses for usinle in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
@@ -475,7 +475,7 @@ static void refit_kdop_hull(BVHTree *tree, BVHNode *node, int start, int end)
}
}
static inline void inflate_kdop_hull(BVHTree *tree, BVHNode *node)
static void inflate_kdop_hull(BVHTree *tree, BVHNode *node)
{
int i;
float *bv = node_get_bv(tree, node);
@@ -924,8 +924,9 @@ static void dfs_find_nearest(BVHNearestData *data, BVHNode *node)
if(node->totnode == 0)
{
data->nearest.dist = sdist;
data->nearest.index = node->index;
VECCOPY(data->nearest.nearest, nearest);
data->nearest.dist = sdist;
}
else
{