diff options
author | Andre Susano Pinto <andresusanopinto@gmail.com> | 2008-06-21 01:10:16 +0400 |
---|---|---|
committer | Andre Susano Pinto <andresusanopinto@gmail.com> | 2008-06-21 01:10:16 +0400 |
commit | 824eac5095924ffdc1fea213a925054c88bf05d7 (patch) | |
tree | fb6545989e9e4739dbe0b77e5922facdb91be60e /source/blender/blenkernel | |
parent | 91f8ad839805a64364f2685a00cc8309688d2f44 (diff) |
Added cut-plane option.
Its now possible to project 2 planes over a model and get a cloth..
Tought it still has a few issues.. related with distance to kept from mesh.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_shrinkwrap.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/shrinkwrap.c | 102 |
3 files changed, 94 insertions, 23 deletions
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index 3eb0b6fa579..b0a40768e8b 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -54,7 +54,7 @@ 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 *original; //mesh before shrinkwrap (TODO clean this variable.. we don't really need it) struct DerivedMesh *final; //initially a copy of original mesh.. mesh thats going to be shrinkwrapped struct DerivedMesh *target; //mesh we are shrinking to diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index cd65aace158..dfd76a9c9d4 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -7022,6 +7022,9 @@ static void shrinkwrapModifier_initData(ModifierData *md) smd->shrinkOpts = MOD_SHRINKWRAP_ALLOW_DEFAULT_NORMAL; smd->keptDist = 0.0f; smd->mergeDist = 0.0f; + + smd->target = 0; + smd->cutPlane = 0; } static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target) @@ -7045,6 +7048,7 @@ static void shrinkwrapModifier_foreachObjectLink(ModifierData *md, Object *ob, O ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md; walk(userData, ob, &smd->target); + walk(userData, ob, &smd->cutPlane); } static DerivedMesh *shrinkwrapModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, int useRenderParams, int isFinalCalc) @@ -7061,12 +7065,11 @@ static void shrinkwrapModifier_updateDepgraph(ModifierData *md, DagForest *fores { ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md; - if (smd->target) { - DagNode *curNode = dag_get_node(forest, smd->target); + if (smd->target) + dag_add_relation(forest, dag_get_node(forest, smd->target), obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier"); - dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, - "Shrinkwrap Modifier"); - } + if (smd->cutPlane) + dag_add_relation(forest, dag_get_node(forest, smd->cutPlane), obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier"); } diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 893cff3dd25..4ae2ad8f4a9 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -894,6 +894,73 @@ static void shrinkwrap_removeUnused(ShrinkwrapCalcData *calc) calc->final = new; } +void shrinkwrap_projectToCutPlane(ShrinkwrapCalcData *calc_data) +{ + if(calc_data->smd->cutPlane && calc_data->moved) + { + int i; + int unmoved = 0; + int numVerts= 0; + MVert *vert = NULL; + MVert *vert_unmoved = NULL; + + ShrinkwrapCalcData calc; + memcpy(&calc, calc_data, sizeof(calc)); + + calc.moved = 0; + + if(calc.smd->cutPlane) + { + calc.target = (DerivedMesh *)calc.smd->cutPlane->derivedFinal; + + if(!calc.target) + { + 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); + + calc.keptDist = 0; + } + + + //Make a mesh with the points we want to project + numVerts = calc_data->final->getNumVerts(calc_data->final); + + unmoved = 0; + for(i=0; i<numVerts; i++) + if(!bitset_get(calc_data->moved, i)) + unmoved++; + + calc.final = CDDM_new(unmoved, 0, 0); + if(!calc.final) return; + + + vert = calc_data->final->getVertDataArray(calc_data->final, CD_MVERT); + vert_unmoved = calc.final->getVertDataArray(calc.final, CD_MVERT); + + for(i=0; i<numVerts; i++) + if(!bitset_get(calc_data->moved, i)) + memcpy(vert_unmoved++, vert+i, sizeof(*vert_unmoved)); + + //use shrinkwrap projection + shrinkwrap_calc_normal_projection(&calc); + + //Copy the points back to the mesh + vert = calc_data->final->getVertDataArray(calc_data->final, CD_MVERT); + vert_unmoved = calc.final->getVertDataArray(calc.final, CD_MVERT); + for(i=0; i<numVerts; i++) + if(!bitset_get(calc_data->moved, i)) + memcpy(vert+i, vert_unmoved++, sizeof(*vert_unmoved) ); + + //free memory + calc.final->release(calc.final); + } + +} + /* Main shrinkwrap function */ DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) @@ -951,11 +1018,29 @@ DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, Deri break; case MOD_SHRINKWRAP_NORMAL: + + if(calc.smd->shrinkOpts & MOD_SHRINKWRAP_REMOVE_UNPROJECTED_FACES) + calc.moved = bitset_new( calc.final->getNumVerts(calc.final), "shrinkwrap bitset data"); + BENCH(shrinkwrap_calc_normal_projection(&calc)); // BENCH(shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_normal_projection)); + + if(calc.moved) + { + //Adjust vertxs that didn't moved (project to cut plane) + shrinkwrap_projectToCutPlane(&calc); + + //Destroy faces, edges and stuff + shrinkwrap_removeUnused(&calc); + + //Merge points that didn't moved + derivedmesh_mergeNearestPoints(calc.final, calc.smd->mergeDist, calc.moved); + bitset_free(calc.moved); + } break; case MOD_SHRINKWRAP_NEAREST_VERTEX: + BENCH(shrinkwrap_calc_nearest_vertex(&calc)); // BENCH(shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_nearest_vertex)); break; @@ -963,22 +1048,8 @@ DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, Deri } - if(calc.moved) - { - //Destroy faces, edges and stuff - shrinkwrap_removeUnused(&calc); - - if(calc.moved) - derivedmesh_mergeNearestPoints(calc.final, calc.smd->mergeDist, calc.moved); - } - CDDM_calc_normals(calc.final); - //clean memory - if(calc.moved) - bitset_free(calc.moved); - - return calc.final; } @@ -1083,9 +1154,6 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) vert = calc->final->getVertDataArray(calc->final, CD_MVERT); dvert = calc->final->getVertDataArray(calc->final, CD_MDEFORMVERT); - if(calc->smd->shrinkOpts & MOD_SHRINKWRAP_REMOVE_UNPROJECTED_FACES) - calc->moved = bitset_new(numVerts, "shrinkwrap bitset data"); - for(i=0; i<numVerts; i++) { float dist = FLT_MAX; |