Revision: 15634
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15634
Author:   jaguarandi
Date:     2008-07-19 00:24:20 +0200 (Sat, 19 Jul 2008)

Log Message:
-----------
*Added "kept" mesh above surface option on shrinkwrap to nearest surface
changed a few code relative to project over normal mode (to try to kept code 
generic and more independent of modifier itself)

Modified Paths:
--------------
    branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h
    branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c
    branches/soc-2008-jaguarandi/source/blender/blenlib/BLI_kdopbvh.h
    branches/soc-2008-jaguarandi/source/blender/blenlib/intern/BLI_kdopbvh.c
    branches/soc-2008-jaguarandi/source/blender/makesdna/DNA_modifier_types.h
    branches/soc-2008-jaguarandi/source/blender/src/buttons_editing.c

Modified: 
branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h
===================================================================
--- branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h     
2008-07-18 22:16:23 UTC (rev 15633)
+++ branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h     
2008-07-18 22:24:20 UTC (rev 15634)
@@ -42,7 +42,27 @@
 #define bitset_unset(set,index)        ((set)[(index)>>3] &= ~(1 << 
((index)&0x7)))
 
 
+/* SpaceTransform stuff */
+//TODO: should move to other generic space?
+struct Object;
 
+typedef struct SpaceTransform
+{
+       float local2target[4][4];
+       float target2local[4][4];
+
+} SpaceTransform;
+
+void space_transform_setup(SpaceTransform *data, struct Object *local, struct 
Object *target);
+
+void space_transform_apply (SpaceTransform *data, float *co);
+void space_transform_invert(SpaceTransform *data, float *co);
+
+void space_transform_apply_normal (SpaceTransform *data, float *co);
+void space_transform_invert_normal(SpaceTransform *data, float *co);
+
+
+/* Shrinkwrap stuff */
 struct Object;
 struct DerivedMesh;
 struct ShrinkwrapModifierData;
@@ -59,9 +79,7 @@
 
        struct DerivedMesh *target;             //mesh we are shrinking to
        
-       //matrixs for local<->target space transform
-       float local2target[4][4];               
-       float target2local[4][4];
+       SpaceTransform local2target;
 
        float keptDist;                                 //Distance to kept from 
target (units are in local space)
        //float *weights;                               //weights of vertexs
@@ -75,6 +93,7 @@
 
 struct DerivedMesh *shrinkwrapModifier_do(struct ShrinkwrapModifierData *smd, 
struct Object *ob, struct DerivedMesh *dm, int useRenderParams, int 
isFinalCalc);
 
+
 #endif
 
 

Modified: 
branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c
===================================================================
--- branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c  
2008-07-18 22:16:23 UTC (rev 15633)
+++ branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c  
2008-07-18 22:24:20 UTC (rev 15634)
@@ -121,7 +121,39 @@
        return FLT_MAX;
 }
 
+/* Space transform */
+void space_transform_setup(SpaceTransform *data, struct Object *local, struct 
Object *target)
+{
+       Mat4Invert(target->imat, target->obmat); //Invserse might be outdated
+       Mat4MulSerie(data->local2target, target->imat, local->obmat, 0, 0, 0, 
0, 0, 0);
+       Mat4Invert(data->target2local, data->local2target);
+}
 
+void space_transform_apply(/* const */ SpaceTransform *data, float *co)
+{
+       VecMat4MulVecfl(co, data->local2target, co);
+//     Mat4Mul3Vecfl(data->local2target, co);
+}
+
+void space_transform_invert(/* const */SpaceTransform *data, float *co)
+{
+       VecMat4MulVecfl(co, data->target2local, co);
+//     Mat4Mul3Vecfl(data->target2local, co);
+}
+
+void space_transform_apply_normal(/* const */ SpaceTransform *data, float *no)
+{
+       Mat4Mul3Vecfl(data->local2target, no);
+       Normalize(no); // TODO: could we just determine de scale value from the 
matrix?
+}
+
+void space_transform_invert_normal(/* const */ SpaceTransform *data, float *no)
+{
+       Mat4Mul3Vecfl(data->target2local, no);
+       Normalize(no); // TODO: could we just determine de scale value from the 
matrix?
+}
+
+
 /*
  * BVH tree from mesh vertices
  */
@@ -328,6 +360,8 @@
                        hit->index = index;
                        hit->dist = dist;
                        VECADDFAC(hit->co, ray->origin, ray->direction, dist);
+
+                       CalcNormFloat(t0, t1, t2, hit->no);
                }
 
                t1 = t2;
@@ -883,25 +917,24 @@
        {
                float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup);
 
-               float orig[3], final[3]; //Coords relative to target
+               float final[3]; //Coords relative to target
                float normal[3];
                float dist;
 
                if(weight == 0.0f) continue;    //Skip vertexs where we have no 
influence
 
-               VecMat4MulVecfl(orig, calc->local2target, vert[i].co);
-               VECCOPY(final, orig);
+               VECCOPY(final, vert[i].co);
+               space_transform_apply(&calc->local2target, final);
 
                //We also need to apply the rotation to normal
                if(calc->smd->shrinkType == MOD_SHRINKWRAP_NORMAL)
                {
                        NormalShortToFloat(normal, vert[i].no);
-                       Mat4Mul3Vecfl(calc->local2target, normal);
-                       Normalize(normal);      //Watch out for scaling (TODO: 
do we really needed a unit-len normal?)
+                       space_transform_apply_normal(&calc->local2target, 
normal);
                }
                (callback)(calc->target, final, normal);
 
-               VecMat4MulVecfl(final, calc->target2local, final);
+               space_transform_invert(&calc->local2target, final);
 
                dist = VecLenf(vert[i].co, final);
                if(dist > 1e-5) weight *= (dist - calc->keptDist)/dist;
@@ -1075,6 +1108,7 @@
        calc->final = new;
 }
 
+
 void shrinkwrap_projectToCutPlane(ShrinkwrapCalcData *calc_data)
 {
        if(calc_data->smd->cutPlane && calc_data->moved)
@@ -1099,10 +1133,7 @@
                                return;
                        }
 
-                       Mat4Invert (calc.smd->cutPlane->imat, 
calc.smd->cutPlane->obmat);       //inverse is outdated
-                       Mat4MulSerie(calc.local2target, 
calc.smd->cutPlane->imat, calc.ob->obmat, 0, 0, 0, 0, 0, 0);
-                       Mat4Invert(calc.target2local, calc.local2target);
-       
+                       space_transform_setup(&calc.local2target, calc.ob, 
calc.smd->cutPlane);
                        calc.keptDist = 0;
                }
 
@@ -1172,12 +1203,10 @@
                        printf("Target derived mesh is null! :S\n");
                }
 
-               //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);
-       
+               //TODO there might be several "bugs" on non-uniform scales 
matrixs.. because it will no longer be nearest surface, not sphere projection
+               //because space has been deformed
+               space_transform_setup(&calc.local2target, ob, smd->target);
+
                calc.keptDist = smd->keptDist;  //TODO: smd->keptDist is in 
global units.. must change to local
        }
 
@@ -1282,7 +1311,8 @@
                float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup);
                if(weight == 0.0f) continue;
 
-               VecMat4MulVecfl(tmp_co, calc->local2target, vert[i].co);
+               VECCOPY(tmp_co, vert[i].co);
+               space_transform_apply(&calc->local2target, tmp_co);
 
                if(nearest.index != -1)
                {
@@ -1296,7 +1326,7 @@
                {
                        float dist;
 
-                       VecMat4MulVecfl(tmp_co, calc->target2local, 
nearest.nearest);
+                       space_transform_invert(&calc->local2target, tmp_co);
                        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
@@ -1314,6 +1344,7 @@
  * it builds a RayTree from the target mesh and then performs a
  * raycast for each vertex (ray direction = normal)
  */
+/*
 void shrinkwrap_calc_normal_projection_raytree(ShrinkwrapCalcData *calc)
 {
        int i;
@@ -1354,7 +1385,6 @@
                Mat4Mul3Vecfl(calc->local2target, tmp_no);      //Watch out for 
scaling on normal
                Normalize(tmp_no);                                              
        //(TODO: do we really needed a unit-len normal? and we could know the 
scale factor before hand?)
 
-
                if(use_normal & MOD_SHRINKWRAP_ALLOW_DEFAULT_NORMAL)
                {
                        dist = raytree_cast_ray(target, tmp_co, tmp_no, 
face_normal);
@@ -1404,7 +1434,62 @@
 
        free_raytree_from_mesh(target);
 }
+*/
 
+
+/*
+ * This function raycast a single vertex and updates the hit if the "hit" is 
considered valid.
+ * Returns TRUE if "hit" was updated.
+ * Opts control whether an hit is valid or not
+ * Supported options are:
+ *     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)
+{
+       float tmp_co[3], tmp_no[3];
+       BVHTreeRayHit hit_tmp;
+       memcpy( &hit_tmp, hit, sizeof(hit_tmp) );
+
+       //Apply space transform (TODO readjust dist)
+       if(transf)
+       {
+               VECCOPY( tmp_co, vert );
+               space_transform_apply( transf, tmp_co );
+               vert = tmp_co;
+
+               VECCOPY( tmp_no, dir );
+               space_transform_apply_normal( transf, tmp_no );
+               dir = tmp_no;
+       }
+
+       hit_tmp.index = -1;
+
+       BLI_bvhtree_ray_cast(tree, vert, dir, &hit_tmp, callback, userdata);
+
+       if(hit_tmp.index != -1)
+       {
+               float dot = INPR( dir, hit_tmp.no);
+
+               if(((options & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) && dot < 0)
+               || ((options & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) && dot > 0))
+                       return FALSE; //Ignore hit
+
+
+               //Inverting space transform (TODO readjust dist)
+               if(transf)
+               {
+                       space_transform_invert( transf, hit_tmp.co );
+                       space_transform_invert_normal( transf, hit_tmp.no );
+               }
+
+               memcpy(hit, &hit_tmp, sizeof(hit_tmp) );
+               return TRUE;
+       }
+       return FALSE;
+}
+
+
 void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
 {
        int i;
@@ -1417,6 +1502,14 @@
        BVHMeshCallbackUserdata userdata;
        BVHTree_RayCastCallback callback = NULL;
 
+
+       //cutTree
+       BVHTree *limit_tree = NULL;
+       BVHMeshCallbackUserdata limit_userdata;
+       BVHTree_RayCastCallback limit_callback = NULL;
+       SpaceTransform local2cut;
+
+
        int     numVerts;
        MVert *vert = NULL;
        MDeformVert *dvert = NULL;
@@ -1429,6 +1522,21 @@
        bvhtree_meshcallbackdata_init(&userdata, calc->target, calc->keptDist);
        callback = mesh_faces_spherecast;
 
+       if(calc->smd->cutPlane)
+       {
+               DerivedMesh * limit_mesh = (DerivedMesh 
*)calc->smd->cutPlane->derivedFinal;
+               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");
+       }
+
+
        //Project each vertex along normal
        numVerts= calc->final->getNumVerts(calc->final);
        vert    = calc->final->getVertDataArray(calc->final, CD_MVERT); 
@@ -1437,69 +1545,39 @@
        for(i=0; i<numVerts; i++)
        {
                float tmp_co[3], tmp_no[3];
+               float lim = 1000;               //TODO: we should use FLT_MAX 
here, but sweepsphere code isnt prepared for that
                float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup);
 
                if(weight == 0.0f) continue;
 
-               //Transform coordinates local->target
-               VecMat4MulVecfl(tmp_co, calc->local2target, vert[i].co);
-
+               VECCOPY(tmp_co, vert[i].co);
                NormalShortToFloat(tmp_no, vert[i].no);
-               Mat4Mul3Vecfl(calc->local2target, tmp_no);      //Watch out for 
scaling on normal

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to