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
path: root/source
diff options
context:
space:
mode:
authorAndre Susano Pinto <andresusanopinto@gmail.com>2008-05-03 02:09:01 +0400
committerAndre Susano Pinto <andresusanopinto@gmail.com>2008-05-03 02:09:01 +0400
commit2b5432e6bb78ac10779b5f2d4206cb155c2daee9 (patch)
tree00b52f36c20f6267b7bd2ee3fdf8113fa878eadd /source
parent9026559ded7eb0607f3c5118ff0b306583910a60 (diff)
Added control over distance to kept form target mesh
Quad bug was fixed by splitting the quads that are feed to RayTree
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h1
-rw-r--r--source/blender/blenkernel/intern/modifier.c2
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c75
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h2
-rw-r--r--source/blender/src/buttons_editing.c3
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);