diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_build.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_build.c | 158 |
1 files changed, 85 insertions, 73 deletions
diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index ebb5bd9ab9b..2399f6e8fc4 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -83,10 +83,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), DerivedMesh *dm = derivedData; DerivedMesh *result; BuildModifierData *bmd = (BuildModifierData*) md; - int i; - int numFaces_dst, numEdges_dst; + int i, j, k; + int numFaces_dst, numEdges_dst, numLoops_dst = 0; int *vertMap, *edgeMap, *faceMap; float frac; + MPoly *mpoly_dst; + MLoop *ml_dst, *ml_src, *mloop_dst; GHashIterator *hashIter; /* maps vert indices in old mesh to indices in new mesh */ GHash *vertHash = BLI_ghash_new(BLI_ghashutil_inthash, @@ -94,106 +96,115 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), /* maps edge indices in new mesh to indices in old mesh */ GHash *edgeHash = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "build ed apply gh"); + GHash *edgeHash2 = BLI_ghash_new(BLI_ghashutil_inthash, + BLI_ghashutil_intcmp, "build ed apply gh"); + + const int numVert_src = dm->getNumVerts(dm); + const int numEdge_src = dm->getNumEdges(dm); + const int numPoly_src = dm->getNumPolys(dm); + MPoly *mpoly_src = dm->getPolyArray(dm); + MLoop *mloop_src = dm->getLoopArray(dm); + MEdge *medge_src = dm->getEdgeArray(dm); + MVert *mvert_src = dm->getVertArray(dm); - const int numVert_src= dm->getNumVerts(dm); - const int numEdge_src= dm->getNumEdges(dm); - const int numFace_src= dm->getNumFaces(dm); vertMap = MEM_callocN(sizeof(*vertMap) * numVert_src, "build modifier vertMap"); for (i = 0; i < numVert_src; i++) vertMap[i] = i; edgeMap = MEM_callocN(sizeof(*edgeMap) * numEdge_src, "build modifier edgeMap"); for (i = 0; i < numEdge_src; i++) edgeMap[i] = i; - faceMap = MEM_callocN(sizeof(*faceMap) * numFace_src, "build modifier faceMap"); - for (i = 0; i < numFace_src; i++) faceMap[i] = i; + faceMap = MEM_callocN(sizeof(*faceMap) * numPoly_src, "build modifier faceMap"); + for (i = 0; i < numPoly_src; i++) faceMap[i] = i; frac = (BKE_curframe(md->scene) - bmd->start) / bmd->length; CLAMP(frac, 0.0f, 1.0f); - numFaces_dst = dm->getNumFaces(dm) * frac; - numEdges_dst = dm->getNumEdges(dm) * frac; + numFaces_dst = numPoly_src * frac; + numEdges_dst = numEdge_src * frac; /* if there's at least one face, build based on faces */ if (numFaces_dst) { + MPoly *mpoly, *mp; + MLoop *ml, *mloop; + MEdge *medge; + if (bmd->randomize) { BLI_array_randomize(faceMap, sizeof(*faceMap), - numFace_src, bmd->seed); + numPoly_src, bmd->seed); } /* get the set of all vert indices that will be in the final mesh, * mapped to the new indices */ + mpoly = mpoly_src; + mloop = mloop_src; for (i = 0; i < numFaces_dst; i++) { - MFace mf; - dm->getFace(dm, faceMap[i], &mf); + mp = mpoly + faceMap[i]; + ml = mloop + mp->loopstart; - if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1))) { - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v1), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - } - if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2))) { - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v2), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - } - if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3))) { - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v3), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); - } - if (mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) { - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v4), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + for (j=0; j<mp->totloop; j++, ml++) { + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml->v))) + BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(ml->v), + SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); } + + numLoops_dst += mp->totloop; } /* get the set of edges that will be in the new mesh (i.e. all edges * that have both verts in the new mesh) */ + medge = medge_src; for (i = 0; i < numEdge_src; i++) { - MEdge me; - dm->getEdge(dm, i, &me); + MEdge *me = medge + i; - if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) && - BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) + if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1)) && + BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2))) { - BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), + j = BLI_ghash_size(edgeHash); + + BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(j), SET_INT_IN_POINTER(i)); + BLI_ghash_insert(edgeHash2, SET_INT_IN_POINTER(i), + SET_INT_IN_POINTER(j)); } } } else if (numEdges_dst) { - if (bmd->randomize) { + MEdge *medge, *me; + + if(bmd->randomize) BLI_array_randomize(edgeMap, sizeof(*edgeMap), numEdge_src, bmd->seed); - } /* get the set of all vert indices that will be in the final mesh, * mapped to the new indices */ + medge = medge_src; for (i = 0; i < numEdges_dst; i++) { - MEdge me; - dm->getEdge(dm, edgeMap[i], &me); + me = medge + edgeMap[i]; - if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))) { - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v1), + if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1))) { + BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me->v1), SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); } - if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) { - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v2), - SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); + if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2))) { + BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me->v2), SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); } } /* get the set of edges that will be in the new mesh - */ + */ for (i = 0; i < numEdges_dst; i++) { - MEdge me; - dm->getEdge(dm, edgeMap[i], &me); - - BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), + j = BLI_ghash_size(edgeHash); + + BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(j), SET_INT_IN_POINTER(edgeMap[i])); + BLI_ghash_insert(edgeHash2, SET_INT_IN_POINTER(edgeMap[i]), + SET_INT_IN_POINTER(j)); } } else { - int numVerts = dm->getNumVerts(dm) * frac; + int numVerts = numVert_src * frac; if (bmd->randomize) { BLI_array_randomize(vertMap, sizeof(*vertMap), @@ -201,11 +212,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), } /* get the set of all vert indices that will be in the final mesh, - * mapped to the new indices - */ + * mapped to the new indices + */ for (i = 0; i < numVerts; i++) { - BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), - SET_INT_IN_POINTER(i)); + BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i)); } } @@ -213,19 +223,20 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), * the mesh */ result = CDDM_from_template(dm, BLI_ghash_size(vertHash), - BLI_ghash_size(edgeHash), numFaces_dst); + BLI_ghash_size(edgeHash), 0, numLoops_dst, numFaces_dst); /* copy the vertices across */ for ( hashIter = BLI_ghashIterator_new(vertHash); !BLI_ghashIterator_isDone(hashIter); - BLI_ghashIterator_step(hashIter)) + BLI_ghashIterator_step(hashIter) + ) { MVert source; MVert *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); - dm->getVert(dm, oldIndex, &source); + source = mvert_src [oldIndex]; dest = CDDM_get_vert(result, newIndex); DM_copy_vert_data(dm, result, oldIndex, newIndex, 1); @@ -239,7 +250,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), MEdge *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i))); - dm->getEdge(dm, oldIndex, &source); + source = medge_src[oldIndex]; dest = CDDM_get_edge(result, i); source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); @@ -249,33 +260,34 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), *dest = source; } + mpoly_dst = CDDM_get_polys(result); + mloop_dst = ml_dst = CDDM_get_loops(result); + /* copy the faces across, remapping indices */ + k = 0; for (i = 0; i < numFaces_dst; i++) { - MFace source; - MFace *dest; - int orig_v4; - - dm->getFace(dm, faceMap[i], &source); - dest = CDDM_get_face(result, i); + MPoly *source; + MPoly *dest; - orig_v4 = source.v4; + source = mpoly_src + faceMap[i]; + dest = mpoly_dst + i; + DM_copy_poly_data(dm, result, faceMap[i], i, 1); - source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); - source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); - source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3))); - if (source.v4) - source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4))); - - DM_copy_face_data(dm, result, faceMap[i], i, 1); - *dest = source; + *dest = *source; + dest->loopstart = k; - test_index_face(dest, &result->faceData, i, (orig_v4 ? 4 : 3)); - } + DM_copy_loop_data(dm, result, source->loopstart, dest->loopstart, dest->totloop); - CDDM_calc_normals(result); + ml_src = mloop_src + source->loopstart; + for (j=0; j<source->totloop; j++, k++, ml_src++, ml_dst++) { + ml_dst->v = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(ml_src->v))); + ml_dst->e = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash2, SET_INT_IN_POINTER(ml_src->e))); + } + } BLI_ghash_free(vertHash, NULL, NULL); BLI_ghash_free(edgeHash, NULL, NULL); + BLI_ghash_free(edgeHash2, NULL, NULL); MEM_freeN(vertMap); MEM_freeN(edgeMap); |