diff options
author | Andre Susano Pinto <andresusanopinto@gmail.com> | 2008-05-03 02:09:01 +0400 |
---|---|---|
committer | Andre Susano Pinto <andresusanopinto@gmail.com> | 2008-05-03 02:09:01 +0400 |
commit | 2b5432e6bb78ac10779b5f2d4206cb155c2daee9 (patch) | |
tree | 00b52f36c20f6267b7bd2ee3fdf8113fa878eadd | |
parent | 9026559ded7eb0607f3c5118ff0b306583910a60 (diff) |
Added control over distance to kept form target mesh
Quad bug was fixed by splitting the quads that are feed to RayTree
-rw-r--r-- | source/blender/blenkernel/BKE_shrinkwrap.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/shrinkwrap.c | 75 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 2 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 3 |
5 files changed, 60 insertions, 23 deletions
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index 0a302b21141..03c3f897dd4 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -48,6 +48,7 @@ typedef struct ShrinkwrapCalcData float local2target[4][4]; float target2local[4][4]; + float keptDist; //Distance to kept from target (units are in local space) //float *weights; //weights of vertexs unsigned char *moved; //boolean indicating if vertex has moved (TODO use bitmaps) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 04c6c6c99f0..194ce65cd86 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -6978,6 +6978,8 @@ static void shrinkwrapModifier_initData(ModifierData *md) { ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md; smd->shrinkType = MOD_SHRINKWRAP_NEAREST_SURFACE; + smd->shrinkOpts = MOD_SHRINKWRAP_ALLOW_DEFAULT_NORMAL; + smd->keptDist = 0.0f; } static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target) diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index f95e696734c..122256aef6f 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -102,14 +102,15 @@ static float vertexgroup_get_weight(MDeformVert *dvert, int index, int vgroup) if(dvert[index].dw[j].def_nr == vgroup) return dvert[index].dw[j].weight; } - return -1; + return 1.0; } /* * Raytree from mesh */ static MVert *raytree_from_mesh_verts = NULL; -static float raytree_from_mesh_start[3] = { 1e10f, 1e10f, 1e10f }; +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; @@ -117,21 +118,33 @@ static int raytree_check_always(Isect *is, int ob, RayFace *face) static void raytree_from_mesh_get_coords(RayFace *face, float **v1, float **v2, float **v3, float **v4) { - MFace *mface= (MFace*)face; + MFace *mface= raytree_from_mesh_faces + (int)face/2 - 1 ; - if(mface == NULL) + if(face == (RayFace*)(-1)) { - *v1 = raytree_from_mesh_start; - *v2 = raytree_from_mesh_start; - *v3 = raytree_from_mesh_start; + *v1 = NULL; //raytree_from_mesh_start; + *v2 = NULL; //raytree_from_mesh_start; + *v3 = NULL; //raytree_from_mesh_start; *v4 = NULL; return; } - *v1= raytree_from_mesh_verts[mface->v1].co; - *v2= raytree_from_mesh_verts[mface->v2].co; - *v3= raytree_from_mesh_verts[mface->v3].co; - *v4= (mface->v4)? raytree_from_mesh_verts[mface->v4].co: NULL; + //Nasty quad splitting + 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; + *v4= NULL; + } + else + { + *v1= raytree_from_mesh_verts[mface->v1].co; + *v2= raytree_from_mesh_verts[mface->v2].co; + *v3= raytree_from_mesh_verts[mface->v3].co; + *v4= NULL; + } } /* @@ -152,7 +165,10 @@ static RayTree* raytree_create_from_mesh(DerivedMesh *mesh) int numFaces= mesh->getNumFaces(mesh); MFace *face = mesh->getFaceDataArray(mesh, CD_MFACE); int numVerts= mesh->getNumVerts(mesh); + + //Initialize static vars raytree_from_mesh_verts = mesh->getVertDataArray(mesh, CD_MVERT); + raytree_from_mesh_faces = face; //calculate bounding box @@ -165,9 +181,16 @@ static RayTree* raytree_create_from_mesh(DerivedMesh *mesh) if(tree == NULL) return NULL; - //Add faces to the RayTree - for(i=0; i<numFaces; i++) - RE_ray_tree_add_face(tree, 0, (RayFace*)(face+i)); + //Add faces to the RayTree (RayTree uses face=0, with some special value to setup things) + for(i=1; i<=numFaces; i++) + { + 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) + if(face[i-1].v4) + RE_ray_tree_add_face(tree, 0, i*2+1); + } RE_ray_tree_done(tree); @@ -193,7 +216,7 @@ static float raytree_cast_ray(RayTree *tree, const float *coord, const float *di isec.mode = RE_RAY_MIRROR; //We want closest intersection isec.lay = -1; isec.face_last = NULL; - isec.faceorig = NULL; + isec.faceorig = (RayFace*)(-1); isec.labda = 1e10f; VECCOPY(isec.start, coord); @@ -429,6 +452,7 @@ static void shrinkwrap_calc_foreach_vertex(ShrinkwrapCalcData *calc, Shrinkwrap_ float orig[3], final[3]; //Coords relative to target float normal[3]; + float dist; if(weight == 0.0f) continue; //Skip vertexs where we have no influence @@ -444,9 +468,11 @@ static void shrinkwrap_calc_foreach_vertex(ShrinkwrapCalcData *calc, Shrinkwrap_ } (callback)(calc->target, final, normal); - VecLerpf(final, orig, final, weight); //linear interpolation + VecMat4MulVecfl(final, calc->target2local, final); - VecMat4MulVecfl(vert[i].co, calc->target2local, final); + dist = VecLenf(vert[i].co, final); + if(dist > 1e-5) weight *= (dist - calc->keptDist)/dist; + VecLerpf(vert[i].co, vert[i].co, final, weight); //linear interpolation } } @@ -484,7 +510,8 @@ DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, Deri 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); - + + calc.keptDist = smd->keptDist; //TODO: smd->keptDist is in global units.. must change to local } calc.moved = NULL; @@ -588,9 +615,11 @@ void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) if(t != -1) { - float weight = 1.0f; + float dist; VecMat4MulVecfl(nearest.co, calc->target2local, nearest.co); + dist = VecLenf(vert[i].co, tmp_co); + if(dist > 1e-5) weight *= (dist - calc->keptDist)/dist; VecLerpf(vert[i].co, vert[i].co, nearest.co, weight); //linear interpolation if(calc->moved) @@ -643,8 +672,7 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) { float dist = FLT_MAX; float weight = vertexgroup_get_weight(dvert, i, vgroup); -// if(weight == 0.0f) continue; - weight = 1.0; + if(weight == 0.0f) continue; //Transform coordinates local->target VecMat4MulVecfl(tmp_co, calc->local2target, vert[i].co); @@ -680,8 +708,13 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) if(ABS(dist) != FLT_MAX) { + float dist_t; + VECADDFAC(tmp_co, tmp_co, tmp_no, dist); VecMat4MulVecfl(tmp_co, calc->target2local, tmp_co); + + dist_t = VecLenf(vert[i].co, tmp_co); + if(dist_t > 1e-5) weight *= (dist_t - calc->keptDist)/dist_t; VecLerpf(vert[i].co, vert[i].co, tmp_co, weight); //linear interpolation if(calc->moved) diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 6dc018c33c0..2a38358c383 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -494,9 +494,9 @@ typedef struct ShrinkwrapModifierData { struct Object *target; /* shrink target */ char vgroup_name[32]; /* optional vertexgroup name */ + float keptDist; /* distance offset from mesh/projection point */ short shrinkType; /* shrink type projection */ short shrinkOpts; /* shrink options */ - short pad[2]; } ShrinkwrapModifierData; /* Shrinkwrap->shrinkType */ diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 2a10c2e5fce..d007ffad020 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1822,7 +1822,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco height = 94; } else if (md->type==eModifierType_Shrinkwrap) { ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md; - height = 67; + height = 86; if (smd->shrinkType == MOD_SHRINKWRAP_NORMAL) height += 19*2; } @@ -2452,6 +2452,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob); uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &smd->target, "Target to shrink to"); + uiDefButF(block, NUM, B_MODIFIER_RECALC, "Offset:", lx,(cy-=19),buttonWidth,19, &smd->keptDist, 0.0f, 100.0f, 1.0f, 0, "Specify distance to kept from the target"); } uiBlockEndAlign(block); |