[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [14632] branches/soc-2008-jaguarandi/ source/blender/blenkernel/intern/shrinkwrap.c: Nearest-vertex mode optimized with kdtrees
André Pinto
andresusanopinto at gmail.com
Thu May 1 03:00:03 CEST 2008
Revision: 14632
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14632
Author: jaguarandi
Date: 2008-05-01 03:00:01 +0200 (Thu, 01 May 2008)
Log Message:
-----------
Nearest-vertex mode optimized with kdtrees
currently uses the kdtree code avaible on blender
Modified Paths:
--------------
branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c
Modified: branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c
===================================================================
--- branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c 2008-04-30 22:42:12 UTC (rev 14631)
+++ branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c 2008-05-01 01:00:01 UTC (rev 14632)
@@ -30,6 +30,7 @@
#include <float.h>
#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)
@@ -45,8 +46,41 @@
#include "BKE_global.h"
#include "BLI_arithb.h"
+#include "BLI_kdtree.h"
+#define TO_STR(a) #a
+#define JOIN(a,b) a##b
+
+#define OUT_OF_MEMORY() ((void)puts("Shrinkwrap: Out of memory"))
+
+/* Benchmark macros */
+#if 1
+
+#define BENCH(a) \
+ do { \
+ clock_t _clock_init = clock(); \
+ (a); \
+ printf("%s: %fms\n", #a, (float)(clock()-_clock_init)*1000/CLOCKS_PER_SEC); \
+ } while(0)
+
+#define BENCH_VAR(name) clock_t JOIN(_bench_step,name) = 0, JOIN(_bench_total,name) = 0
+#define BENCH_BEGIN(name) JOIN(_bench_step, name) = clock()
+#define BENCH_END(name) JOIN(_bench_total,name) += clock() - JOIN(_bench_step,name)
+#define BENCH_RESET(name) JOIN(_bench_total, name) = 0
+#define BENCH_REPORT(name) printf("%s: %fms\n", TO_STR(name), JOIN(_bench_total,name)*1000.0f/CLOCKS_PER_SEC)
+
+#else
+
+#define BENCH(a) (a)
+#define BENCH_VAR(name)
+#define BENCH_BEGIN(name)
+#define BENCH_END(name)
+#define BENCH_RESET(name)
+#define BENCH_REPORT(name)
+
+#endif
+
#define CONST
typedef void ( *Shrinkwrap_ForeachVertexCallback) (DerivedMesh *target, float *co, float *normal);
@@ -317,15 +351,22 @@
DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
{
- ShrinkwrapCalcData calc;
+ ShrinkwrapCalcData calc = {};
//Init Shrinkwrap calc data
calc.smd = smd;
+ calc.ob = ob;
calc.original = dm;
calc.final = CDDM_copy(calc.original);
+ if(!calc.final)
+ {
+ OUT_OF_MEMORY();
+ return dm;
+ }
+
if(smd->target)
{
calc.target = (DerivedMesh *)smd->target->derivedFinal;
@@ -349,19 +390,24 @@
//Projecting target defined - lets work!
if(calc.target)
{
+ printf("Shrinkwrap (%s)%d over (%s)%d\n",
+ calc.ob->id.name, calc.final->getNumVerts(calc.final),
+ calc.smd->target->id.name, calc.target->getNumVerts(calc.target)
+ );
+
switch(smd->shrinkType)
{
case MOD_SHRINKWRAP_NEAREST_SURFACE:
-// shrinkwrap_calc_nearest_vertex(&calc);
- shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_nearest_surface_point);
+ BENCH(shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_nearest_surface_point));
break;
case MOD_SHRINKWRAP_NORMAL:
- shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_nearest_surface_point);
+ BENCH(shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_normal_projection));
break;
case MOD_SHRINKWRAP_NEAREST_VERTEX:
- shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_nearest_vertex);
+ BENCH(shrinkwrap_calc_nearest_vertex(&calc));
+// BENCH(shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_nearest_vertex));
break;
}
@@ -378,4 +424,65 @@
return calc.final;
}
+void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
+{
+ int i;
+ KDTree* target = NULL;
+ KDTreeNearest nearest;
+ float tmp_co[3];
+ BENCH_VAR(build);
+ BENCH_VAR(query);
+
+ int numVerts;
+ MVert *vert = NULL;
+
+ //Generate kd-tree with target vertexs
+ BENCH_BEGIN(build);
+
+ target = BLI_kdtree_new(calc->target->getNumVerts(calc->target));
+ if(target == NULL) return OUT_OF_MEMORY();
+
+ numVerts= calc->target->getNumVerts(calc->target);
+ vert = calc->target->getVertDataArray(calc->target, CD_MVERT);
+
+ for( ;numVerts--; vert++)
+ BLI_kdtree_insert(target, 0, vert->co, NULL);
+
+ BLI_kdtree_balance(target);
+
+ BENCH_END(build);
+
+ //Find the nearest vertex
+ numVerts= calc->final->getNumVerts(calc->final);
+ vert = calc->final->getVertDataArray(calc->final, CD_MVERT);
+ for(i=0; i<numVerts; i++)
+ {
+ int t;
+ VecMat4MulVecfl(tmp_co, calc->local2target, vert[i].co);
+
+ BENCH_BEGIN(query);
+ t = BLI_kdtree_find_nearest(target, tmp_co, 0, &nearest);
+ BENCH_END(query);
+
+ if(t != -1)
+ {
+ float weight = 1.0f;
+
+ VecMat4MulVecfl(nearest.co, calc->target2local, nearest.co);
+ VecLerpf(vert[i].co, vert[i].co, nearest.co, weight); //linear interpolation
+
+ if(calc->moved)
+ calc->moved[i] = TRUE;
+ }
+ }
+
+ BENCH_BEGIN(build);
+ BLI_kdtree_free(target);
+ BENCH_END(build);
+
+
+ BENCH_REPORT(build);
+ BENCH_REPORT(query);
+}
+
More information about the Bf-blender-cvs
mailing list