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-04-30 21:55:26 +0400
committerAndre Susano Pinto <andresusanopinto@gmail.com>2008-04-30 21:55:26 +0400
commit29f0f74b05462e9bd0b641602b89fa1c39ed29c8 (patch)
tree74dd34d54116a01c7c96b77405fdd0127d98a656 /source/blender/blenkernel
parent928b676b990486d89afa57479b85d8356e07d2d5 (diff)
Changed a bit of code structure to make method optimization easier
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h24
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c169
2 files changed, 120 insertions, 73 deletions
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index 4fd1ae354cd..0a302b21141 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -33,6 +33,30 @@ struct Object;
struct DerivedMesh;
struct ShrinkwrapModifierData;
+
+typedef struct ShrinkwrapCalcData
+{
+ ShrinkwrapModifierData *smd; //shrinkwrap modifier data
+
+ struct Object *ob; //object we are applying shrinkwrap to
+ struct DerivedMesh *original; //mesh before shrinkwrap
+ struct DerivedMesh *final; //initially a copy of original mesh.. mesh thats going to be shrinkwrapped
+
+ struct DerivedMesh *target; //mesh we are shrinking to
+
+ //matrixs for local<->target space transform
+ float local2target[4][4];
+ float target2local[4][4];
+
+ //float *weights; //weights of vertexs
+ unsigned char *moved; //boolean indicating if vertex has moved (TODO use bitmaps)
+
+} ShrinkwrapCalcData;
+
+void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *data);
+void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *data);
+void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *data);
+
struct DerivedMesh *shrinkwrapModifier_do(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm, int useRenderParams, int isFinalCalc);
#endif
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 74e105125ca..606f8938985 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -46,7 +46,10 @@
#include "BLI_arithb.h"
+
#define CONST
+typedef void ( *Shrinkwrap_ForeachVertexCallback) (DerivedMesh *target, float *co, float *normal);
+
static void normal_short2float(CONST short *ns, float *nf)
{
@@ -55,6 +58,7 @@ static void normal_short2float(CONST short *ns, float *nf)
nf[2] = ns[2] / 32767.0f;
}
+
/*
* This calculates the distance (in dir units) that the ray must travel to intersect plane
* It can return negative values
@@ -134,7 +138,7 @@ static float nearest_point_in_tri_surface(CONST float *co, CONST float *v0, CONS
/*
* Shrink to nearest surface point on target mesh
*/
-static void shrinkwrap_calc_nearest_surface_point(DerivedMesh *target, float *co, float *unused)
+static void bruteforce_shrinkwrap_calc_nearest_surface_point(DerivedMesh *target, float *co, float *unused)
{
//TODO: this should use raycast code probably existent in blender
float minDist = FLT_MAX;
@@ -179,7 +183,7 @@ static void shrinkwrap_calc_nearest_surface_point(DerivedMesh *target, float *co
/*
* Projects the vertex on the normal direction over the target mesh
*/
-static void shrinkwrap_calc_normal_projection(DerivedMesh *target, float *co, float *vnormal)
+static void bruteforce_shrinkwrap_calc_normal_projection(DerivedMesh *target, float *co, float *vnormal)
{
//TODO: this should use raycast code probably existent in blender
float minDist = FLT_MAX;
@@ -230,7 +234,7 @@ static void shrinkwrap_calc_normal_projection(DerivedMesh *target, float *co, fl
/*
* Shrink to nearest vertex on target mesh
*/
-static void shrinkwrap_calc_nearest_vertex(DerivedMesh *target, float *co, float *unused)
+static void bruteforce_shrinkwrap_calc_nearest_vertex(DerivedMesh *target, float *co, float *unused)
{
float minDist = FLT_MAX;
float orig_co[3];
@@ -255,104 +259,123 @@ static void shrinkwrap_calc_nearest_vertex(DerivedMesh *target, float *co, float
}
}
-/* Main shrinkwrap function */
-DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
+
+static void shrinkwrap_calc_foreach_vertex(ShrinkwrapCalcData *calc, Shrinkwrap_ForeachVertexCallback callback)
{
+ int i, j;
+ int vgroup = get_named_vertexgroup_num(calc->ob, calc->smd->vgroup_name);
+ int numVerts = 0;
- DerivedMesh *result = CDDM_copy(dm);
+ MDeformVert *dvert = NULL;
+ MVert *vert = NULL;
- //Projecting target defined - lets work!
- if(smd->target)
+ numVerts = calc->final->getNumVerts(calc->final);
+ dvert = calc->final->getVertDataArray(calc->final, CD_MDEFORMVERT);
+ vert = calc->final->getVertDataArray(calc->final, CD_MVERT);
+
+ //Shrink (calculate each vertex final position)
+ for(i = 0; i<numVerts; i++)
{
- int i, j;
+ float weight;
- int vgroup = get_named_vertexgroup_num(ob, smd->vgroup_name);
- int numVerts = 0;
+ float orig[3], final[3]; //Coords relative to target
+ float normal[3];
- MDeformVert *dvert = NULL;
- MVert *vert = NULL;
- DerivedMesh *target_dm = NULL;
+ if(dvert && vgroup >= 0)
+ {
+ weight = 0.0f;
+ for(j = 0; j < dvert[i].totweight; j++)
+ if(dvert[i].dw[j].def_nr == vgroup)
+ {
+ weight = dvert[i].dw[j].weight;
+ break;
+ }
+ }
+ else weight = 1.0f;
- float local2target[4][4], target2local[4][4];
+ if(weight == 0.0f) continue; //Skip vertexs where we have no influence
- numVerts = result->getNumVerts(result);
- dvert = result->getVertDataArray(result, CD_MDEFORMVERT);
- vert = result->getVertDataArray(result, CD_MVERT);
+ VecMat4MulVecfl(orig, calc->local2target, vert[i].co);
+ VECCOPY(final, orig);
- target_dm = (DerivedMesh *)smd->target->derivedFinal;
- if(!target_dm)
+ //We also need to apply the rotation to normal
+ if(calc->smd->shrinkType == MOD_SHRINKWRAP_NORMAL)
{
- printf("Target derived mesh is null! :S\n");
+ normal_short2float(vert[i].no, normal);
+ Mat4Mul3Vecfl(calc->local2target, normal);
+ Normalize(normal); //Watch out for scaling (TODO: do we really needed a unit-len normal?)
}
+ (callback)(calc->target, final, normal);
+ VecLerpf(final, orig, final, weight); //linear interpolation
- //TODO should we reduce the number of matrix mults? by choosing applying matrixs to target or to derived mesh?
- //Calculate matrixs for local <-> target
- Mat4Invert (smd->target->imat, smd->target->obmat); //inverse is outdated
-
- Mat4MulSerie(local2target, smd->target->imat, ob->obmat, 0, 0, 0, 0, 0, 0);
- Mat4Invert(target2local, local2target);
-
+ VecMat4MulVecfl(vert[i].co, calc->target2local, final);
+ }
+}
- //Shrink (calculate each vertex final position)
- for(i = 0; i<numVerts; i++)
- {
- float weight;
+/* Main shrinkwrap function */
+DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
+{
- float orig[3], final[3]; //Coords relative to target_dm
- float normal[3];
+ ShrinkwrapCalcData calc;
- if(dvert && vgroup >= 0)
- {
- weight = 0.0f;
- for(j = 0; j < dvert[i].totweight; j++)
- if(dvert[i].dw[j].def_nr == vgroup)
- {
- weight = dvert[i].dw[j].weight;
- break;
- }
- }
- else weight = 1.0f;
- if(weight == 0.0f) continue; //Skip vertexs where we have no influence
+ //Init Shrinkwrap calc data
+ calc.smd = smd;
- VecMat4MulVecfl(orig, local2target, vert[i].co);
- VECCOPY(final, orig);
+ calc.original = dm;
+ calc.final = CDDM_copy(calc.original);
- //We also need to apply the rotation to normal
- if(smd->shrinkType == MOD_SHRINKWRAP_NORMAL)
- {
- normal_short2float(vert[i].no, normal);
- Mat4Mul3Vecfl(local2target, normal);
- Normalize(normal); //Watch out for scaling (TODO: do we really needed a unit-len normal?)
- }
+ if(smd->target)
+ {
+ calc.target = (DerivedMesh *)smd->target->derivedFinal;
+ if(!calc.target)
+ {
+ printf("Target derived mesh is null! :S\n");
+ }
- switch(smd->shrinkType)
- {
- case MOD_SHRINKWRAP_NEAREST_SURFACE:
- shrinkwrap_calc_nearest_surface_point(target_dm, final, normal);
- break;
+ //TODO should we reduce the number of matrix mults? by choosing applying matrixs to target or to derived mesh?
+ //Calculate matrixs for local <-> target
+ Mat4Invert (smd->target->imat, smd->target->obmat); //inverse is outdated
+ Mat4MulSerie(calc.local2target, smd->target->imat, ob->obmat, 0, 0, 0, 0, 0, 0);
+ Mat4Invert(calc.target2local, calc.local2target);
- case MOD_SHRINKWRAP_NORMAL:
- shrinkwrap_calc_normal_projection(target_dm, final, normal);
- break;
+ }
- case MOD_SHRINKWRAP_NEAREST_VERTEX:
- shrinkwrap_calc_nearest_vertex(target_dm, final, normal);
- break;
- }
+ calc.moved = NULL;
- VecLerpf(final, orig, final, weight); //linear interpolation
- VecMat4MulVecfl(vert[i].co, target2local, final);
+ //Projecting target defined - lets work!
+ if(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);
+ break;
+
+ case MOD_SHRINKWRAP_NORMAL:
+ shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_nearest_surface_point);
+ break;
+
+ case MOD_SHRINKWRAP_NEAREST_VERTEX:
+ shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_nearest_vertex);
+ break;
}
- //Destroy faces, edges and stuff
- //Since we aren't yet constructing/destructing geom nothing todo for now
- CDDM_calc_normals(result);
+ }
+ //Destroy faces, edges and stuff
+ if(calc.moved)
+ {
+ //TODO
}
- return result;
+
+ CDDM_calc_normals(calc.final);
+
+ return calc.final;
}
+