diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2012-07-21 06:09:11 +0400 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2012-07-21 06:09:11 +0400 |
commit | d4ff8f911cf0e7b996c3ea7e3edc5aeb9af3ba8d (patch) | |
tree | 3ab2527acfa25f78f11bea876eb4827d0f7067cc /source/blender/modifiers/intern | |
parent | 4ae1d51db54cc16a1fe34bf9ece459a163e9a69d (diff) |
UV mirrored unwrap
===================
* Separate common mirror functionality from modifier files to BKE_*
files
* Now subsurfed unwrap can flush the result of the mirrored mesh to the
solver
* TODO: add support for regular unwrap, pack the result to 0.0-0.5 range
if the appropriate mirror uv option is selected in the modifier
Diffstat (limited to 'source/blender/modifiers/intern')
-rw-r--r-- | source/blender/modifiers/intern/MOD_mirror.c | 239 |
1 files changed, 3 insertions, 236 deletions
diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index 6f3d47b3426..c2ca8472be7 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -33,20 +33,14 @@ */ -#include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "BLI_math.h" -#include "BLI_array.h" +#include "BLI_utildefines.h" #include "BKE_cdderivedmesh.h" -#include "BKE_mesh.h" #include "BKE_modifier.h" -#include "BKE_deform.h" -#include "BKE_utildefines.h" -#include "BKE_tessmesh.h" +#include "BKE_mirror.h" -#include "MEM_guardedalloc.h" #include "depsgraph_private.h" static void initData(ModifierData *md) @@ -92,233 +86,7 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } } -static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, - Object *ob, - DerivedMesh *dm, - int axis) -{ - const float tolerance_sq = mmd->tolerance * mmd->tolerance; - const int do_vtargetmap = !(mmd->flag & MOD_MIR_NO_MERGE); - int is_vtargetmap = FALSE; /* true when it should be used */ - - DerivedMesh *result; - const int maxVerts = dm->getNumVerts(dm); - const int maxEdges = dm->getNumEdges(dm); - const int maxLoops = dm->getNumLoops(dm); - const int maxPolys = dm->getNumPolys(dm); - MVert *mv, *mv_prev; - MEdge *me; - MLoop *ml; - MPoly *mp; - float mtx[4][4]; - int i, j; - int a, totshape; - int *vtargetmap = NULL, *vtmap_a = NULL, *vtmap_b = NULL; - - /* mtx is the mirror transformation */ - unit_m4(mtx); - mtx[axis][axis] = -1.0f; - - if (mmd->mirror_ob) { - float tmp[4][4]; - float itmp[4][4]; - - /* tmp is a transform from coords relative to the object's own origin, - * to coords relative to the mirror object origin */ - invert_m4_m4(tmp, mmd->mirror_ob->obmat); - mult_m4_m4m4(tmp, tmp, ob->obmat); - - /* itmp is the reverse transform back to origin-relative coordinates */ - invert_m4_m4(itmp, tmp); - - /* combine matrices to get a single matrix that translates coordinates into - * mirror-object-relative space, does the mirror, and translates back to - * origin-relative space */ - mult_m4_m4m4(mtx, mtx, tmp); - mult_m4_m4m4(mtx, itmp, mtx); - } - - result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, 0, maxLoops * 2, maxPolys * 2); - - /*copy customdata to original geometry*/ - DM_copy_vert_data(dm, result, 0, 0, maxVerts); - DM_copy_edge_data(dm, result, 0, 0, maxEdges); - DM_copy_loop_data(dm, result, 0, 0, maxLoops); - DM_copy_poly_data(dm, result, 0, 0, maxPolys); - - - /* subsurf for eg wont have mesh data in the */ - /* now add mvert/medge/mface layers */ - - if (!CustomData_has_layer(&dm->vertData, CD_MVERT)) { - dm->copyVertArray(dm, CDDM_get_verts(result)); - } - if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE)) { - dm->copyEdgeArray(dm, CDDM_get_edges(result)); - } - if (!CustomData_has_layer(&dm->polyData, CD_MPOLY)) { - dm->copyLoopArray(dm, CDDM_get_loops(result)); - dm->copyPolyArray(dm, CDDM_get_polys(result)); - } - - /* copy customdata to new geometry, - * copy from its self because this data may have been created in the checks above */ - DM_copy_vert_data(result, result, 0, maxVerts, maxVerts); - DM_copy_edge_data(result, result, 0, maxEdges, maxEdges); - /* loops are copied later */ - DM_copy_poly_data(result, result, 0, maxPolys, maxPolys); - - if (do_vtargetmap) { - /* second half is filled with -1 */ - vtargetmap = MEM_mallocN(sizeof(int) * maxVerts * 2, "MOD_mirror tarmap"); - - vtmap_a = vtargetmap; - vtmap_b = vtargetmap + maxVerts; - } - - /* mirror vertex coordinates */ - mv_prev = CDDM_get_verts(result); - mv = mv_prev + maxVerts; - for (i = 0; i < maxVerts; i++, mv++, mv_prev++) { - mul_m4_v3(mtx, mv->co); - if (do_vtargetmap) { - /* compare location of the original and mirrored vertex, to see if they - * should be mapped for merging */ - if (UNLIKELY(len_squared_v3v3(mv_prev->co, mv->co) < tolerance_sq)) { - *vtmap_a = maxVerts + i; - is_vtargetmap = TRUE; - } - else { - *vtmap_a = -1; - } - - *vtmap_b = -1; /* fill here to avoid 2x loops */ - - vtmap_a++; - vtmap_b++; - } - } - - /* handle shape keys */ - totshape = CustomData_number_of_layers(&result->vertData, CD_SHAPEKEY); - for (a = 0; a < totshape; a++) { - float (*cos)[3] = CustomData_get_layer_n(&result->vertData, CD_SHAPEKEY, a); - for (i = maxVerts; i < result->numVertData; i++) { - mul_m4_v3(mtx, cos[i]); - } - } - - /* adjust mirrored edge vertex indices */ - me = CDDM_get_edges(result) + maxEdges; - for (i = 0; i < maxEdges; i++, me++) { - me->v1 += maxVerts; - me->v2 += maxVerts; - } - - /* adjust mirrored poly loopstart indices, and reverse loop order (normals) */ - mp = CDDM_get_polys(result) + maxPolys; - ml = CDDM_get_loops(result); - for (i = 0; i < maxPolys; i++, mp++) { - MLoop *ml2; - int e; - - /* reverse the loop, but we keep the first vertex in the face the same, - * to ensure that quads are split the same way as on the other side */ - DM_copy_loop_data(result, result, mp->loopstart, mp->loopstart + maxLoops, 1); - for (j = 1; j < mp->totloop; j++) - DM_copy_loop_data(result, result, mp->loopstart + j, mp->loopstart + maxLoops + mp->totloop - j, 1); - - ml2 = ml + mp->loopstart + maxLoops; - e = ml2[0].e; - for (j = 0; j < mp->totloop - 1; j++) { - ml2[j].e = ml2[j + 1].e; - } - ml2[mp->totloop - 1].e = e; - - mp->loopstart += maxLoops; - } - - /* adjust mirrored loop vertex and edge indices */ - ml = CDDM_get_loops(result) + maxLoops; - for (i = 0; i < maxLoops; i++, ml++) { - ml->v += maxVerts; - ml->e += maxEdges; - } - - /* handle uvs, - * let tessface recalc handle updating the MTFace data */ - if (mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V)) { - const int do_mirr_u = (mmd->flag & MOD_MIR_MIRROR_U) != 0; - const int do_mirr_v = (mmd->flag & MOD_MIR_MIRROR_V) != 0; - - const int totuv = CustomData_number_of_layers(&result->loopData, CD_MLOOPUV); - - for (a = 0; a < totuv; a++) { - MLoopUV *dmloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, a); - int j = maxLoops; - dmloopuv += j; /* second set of loops only */ - for (; j-- > 0; dmloopuv++) { - if (do_mirr_u) dmloopuv->uv[0] = 1.0f - dmloopuv->uv[0]; - if (do_mirr_v) dmloopuv->uv[1] = 1.0f - dmloopuv->uv[1]; - } - } - } - - /* handle vgroup stuff */ - if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&result->vertData, CD_MDEFORMVERT)) { - MDeformVert *dvert = (MDeformVert *) CustomData_get_layer(&result->vertData, CD_MDEFORMVERT) + maxVerts; - int *flip_map = NULL, flip_map_len = 0; - - flip_map = defgroup_flip_map(ob, &flip_map_len, FALSE); - - if (flip_map) { - for (i = 0; i < maxVerts; dvert++, i++) { - /* merged vertices get both groups, others get flipped */ - if (do_vtargetmap && (vtargetmap[i] != -1)) - defvert_flip_merged(dvert, flip_map, flip_map_len); - else - defvert_flip(dvert, flip_map, flip_map_len); - } - - MEM_freeN(flip_map); - } - } - - if (do_vtargetmap) { - /* slow - so only call if one or more merge verts are found, - * users may leave this on and not realize there is nothing to merge - campbell */ - if (is_vtargetmap) { - result = CDDM_merge_verts(result, vtargetmap); - } - MEM_freeN(vtargetmap); - } - - return result; -} - -static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, - Object *ob, DerivedMesh *dm) -{ - DerivedMesh *result = dm; - - /* check which axes have been toggled and mirror accordingly */ - if (mmd->flag & MOD_MIR_AXIS_X) { - result = doMirrorOnAxis(mmd, ob, result, 0); - } - if (mmd->flag & MOD_MIR_AXIS_Y) { - DerivedMesh *tmp = result; - result = doMirrorOnAxis(mmd, ob, result, 1); - if (tmp != dm) tmp->release(tmp); /* free intermediate results */ - } - if (mmd->flag & MOD_MIR_AXIS_Z) { - DerivedMesh *tmp = result; - result = doMirrorOnAxis(mmd, ob, result, 2); - if (tmp != dm) tmp->release(tmp); /* free intermediate results */ - } - - return result; -} static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, @@ -327,7 +95,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *result; MirrorModifierData *mmd = (MirrorModifierData *) md; - result = mirrorModifier__doMirror(mmd, ob, derivedData); + result = mirror_make_derived_from_derived(mmd, ob, derivedData, FALSE); if (result != derivedData) CDDM_calc_normals(result); @@ -342,7 +110,6 @@ static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, return applyModifier(md, ob, derivedData, MOD_APPLY_USECACHE); } - ModifierTypeInfo modifierType_Mirror = { /* name */ "Mirror", /* structName */ "MirrorModifierData", |