diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_array.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_array.c | 866 |
1 files changed, 433 insertions, 433 deletions
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 3a34b048aa3..90954fef1c7 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -313,60 +313,60 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, else /* if the offset has no translation, just make one copy */ count = 1; - } + } - if(count < 1) - count = 1; + if(count < 1) + count = 1; /* allocate memory for count duplicates (including original) plus * start and end caps */ - finalVerts = dm->getNumVerts(dm) * count; - finalEdges = dm->getNumEdges(dm) * count; - finalFaces = dm->getNumFaces(dm) * count; - if(start_cap) { - finalVerts += start_cap->getNumVerts(start_cap); - finalEdges += start_cap->getNumEdges(start_cap); - finalFaces += start_cap->getNumFaces(start_cap); - } - if(end_cap) { - finalVerts += end_cap->getNumVerts(end_cap); - finalEdges += end_cap->getNumEdges(end_cap); - finalFaces += end_cap->getNumFaces(end_cap); - } - result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces); - - /* calculate the offset matrix of the final copy (for merging) */ - unit_m4(final_offset); - - for(j=0; j < count - 1; j++) { - mul_m4_m4m4(tmp_mat, final_offset, offset); - copy_m4_m4(final_offset, tmp_mat); - } - - numVerts = numEdges = numFaces = 0; - mvert = CDDM_get_verts(result); - - for (i = 0; i < maxVerts; i++) { - indexMap[i].merge = -1; /* default to no merge */ - indexMap[i].merge_final = 0; /* default to no merge */ - } - - for (i = 0; i < maxVerts; i++) { - MVert *inMV; - MVert *mv = &mvert[numVerts]; - MVert *mv2; - float co[3]; - - inMV = &src_mvert[i]; - - DM_copy_vert_data(dm, result, i, numVerts, 1); - *mv = *inMV; - numVerts++; - - indexMap[i].new = numVerts - 1; - - copy_v3_v3(co, mv->co); + finalVerts = dm->getNumVerts(dm) * count; + finalEdges = dm->getNumEdges(dm) * count; + finalFaces = dm->getNumFaces(dm) * count; + if(start_cap) { + finalVerts += start_cap->getNumVerts(start_cap); + finalEdges += start_cap->getNumEdges(start_cap); + finalFaces += start_cap->getNumFaces(start_cap); + } + if(end_cap) { + finalVerts += end_cap->getNumVerts(end_cap); + finalEdges += end_cap->getNumEdges(end_cap); + finalFaces += end_cap->getNumFaces(end_cap); + } + result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces); + + /* calculate the offset matrix of the final copy (for merging) */ + unit_m4(final_offset); + + for(j=0; j < count - 1; j++) { + mul_m4_m4m4(tmp_mat, final_offset, offset); + copy_m4_m4(final_offset, tmp_mat); + } + + numVerts = numEdges = numFaces = 0; + mvert = CDDM_get_verts(result); + + for (i = 0; i < maxVerts; i++) { + indexMap[i].merge = -1; /* default to no merge */ + indexMap[i].merge_final = 0; /* default to no merge */ + } + + for (i = 0; i < maxVerts; i++) { + MVert *inMV; + MVert *mv = &mvert[numVerts]; + MVert *mv2; + float co[3]; + + inMV = &src_mvert[i]; + + DM_copy_vert_data(dm, result, i, numVerts, 1); + *mv = *inMV; + numVerts++; + + indexMap[i].new = numVerts - 1; + + copy_v3_v3(co, mv->co); /* Attempts to merge verts from one duplicate with verts from the * next duplicate which are closer than amd->merge_dist. @@ -374,405 +374,405 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, * If verts are merged in the first duplicate pair, they are merged * in all pairs. */ - if((count > 1) && (amd->flags & MOD_ARR_MERGE)) { - float tmp_co[3]; - mul_v3_m4v3(tmp_co, offset, mv->co); - - for(j = 0; j < maxVerts; j++) { - /* if vertex already merged, don't use it */ - if( indexMap[j].merge != -1 ) continue; - - inMV = &src_mvert[j]; - /* if this vert is within merge limit, merge */ - if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) { - indexMap[i].merge = j; - - /* test for merging with final copy of merge target */ - if(amd->flags & MOD_ARR_MERGEFINAL) { - copy_v3_v3(tmp_co, inMV->co); - inMV = &src_mvert[i]; - mul_m4_v3(final_offset, tmp_co); - if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) - indexMap[i].merge_final = 1; - } - break; - } - } - } - - /* if no merging, generate copies of this vert */ - if(indexMap[i].merge < 0) { - for(j=0; j < count - 1; j++) { - mv2 = &mvert[numVerts]; - - DM_copy_vert_data(result, result, numVerts - 1, numVerts, 1); - *mv2 = *mv; - numVerts++; - - mul_m4_v3(offset, co); - copy_v3_v3(mv2->co, co); - } - } else if(indexMap[i].merge != i && indexMap[i].merge_final) { + if((count > 1) && (amd->flags & MOD_ARR_MERGE)) { + float tmp_co[3]; + mul_v3_m4v3(tmp_co, offset, mv->co); + + for(j = 0; j < maxVerts; j++) { + /* if vertex already merged, don't use it */ + if( indexMap[j].merge != -1 ) continue; + + inMV = &src_mvert[j]; + /* if this vert is within merge limit, merge */ + if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) { + indexMap[i].merge = j; + + /* test for merging with final copy of merge target */ + if(amd->flags & MOD_ARR_MERGEFINAL) { + copy_v3_v3(tmp_co, inMV->co); + inMV = &src_mvert[i]; + mul_m4_v3(final_offset, tmp_co); + if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) + indexMap[i].merge_final = 1; + } + break; + } + } + } + + /* if no merging, generate copies of this vert */ + if(indexMap[i].merge < 0) { + for(j=0; j < count - 1; j++) { + mv2 = &mvert[numVerts]; + + DM_copy_vert_data(result, result, numVerts - 1, numVerts, 1); + *mv2 = *mv; + numVerts++; + + mul_m4_v3(offset, co); + copy_v3_v3(mv2->co, co); + } + } else if(indexMap[i].merge != i && indexMap[i].merge_final) { /* if this vert is not merging with itself, and it is merging * with the final copy of its merge target, remove the first copy */ - numVerts--; - DM_free_vert_data(result, numVerts, 1); - } - } + numVerts--; + DM_free_vert_data(result, numVerts, 1); + } + } - /* make a hashtable so we can avoid duplicate edges from merging */ - edges = BLI_edgehash_new(); + /* make a hashtable so we can avoid duplicate edges from merging */ + edges = BLI_edgehash_new(); - maxEdges = dm->getNumEdges(dm); - medge = CDDM_get_edges(result); - for(i = 0; i < maxEdges; i++) { - MEdge inMED; - MEdge med; - MEdge *med2; - int vert1, vert2; + maxEdges = dm->getNumEdges(dm); + medge = CDDM_get_edges(result); + for(i = 0; i < maxEdges; i++) { + MEdge inMED; + MEdge med; + MEdge *med2; + int vert1, vert2; - dm->getEdge(dm, i, &inMED); + dm->getEdge(dm, i, &inMED); - med = inMED; - med.v1 = indexMap[inMED.v1].new; - med.v2 = indexMap[inMED.v2].new; + med = inMED; + med.v1 = indexMap[inMED.v1].new; + med.v2 = indexMap[inMED.v2].new; /* if vertices are to be merged with the final copies of their * merge targets, calculate that final copy */ - if(indexMap[inMED.v1].merge_final) { - med.v1 = calc_mapping(indexMap, indexMap[inMED.v1].merge, - count - 1); - } - if(indexMap[inMED.v2].merge_final) { - med.v2 = calc_mapping(indexMap, indexMap[inMED.v2].merge, - count - 1); - } - - if(med.v1 == med.v2) continue; - - /* XXX Unfortunately the calc_mapping returns sometimes numVerts... leads to bad crashes */ - if(med.v1 >= numVerts) - med.v1= numVerts-1; - if(med.v2 >= numVerts) - med.v2= numVerts-1; - - if (initFlags) { - med.flag |= ME_EDGEDRAW | ME_EDGERENDER; - } - - if(!BLI_edgehash_haskey(edges, med.v1, med.v2)) { - DM_copy_edge_data(dm, result, i, numEdges, 1); - medge[numEdges] = med; - numEdges++; - - BLI_edgehash_insert(edges, med.v1, med.v2, NULL); - } - - for(j = 1; j < count; j++) - { - vert1 = calc_mapping(indexMap, inMED.v1, j); - vert2 = calc_mapping(indexMap, inMED.v2, j); - - /* edge could collapse to single point after mapping */ - if(vert1 == vert2) continue; - - /* XXX Unfortunately the calc_mapping returns sometimes numVerts... leads to bad crashes */ - if(vert1 >= numVerts) - vert1= numVerts-1; - if(vert2 >= numVerts) - vert2= numVerts-1; - - /* avoid duplicate edges */ - if(!BLI_edgehash_haskey(edges, vert1, vert2)) { - med2 = &medge[numEdges]; - - DM_copy_edge_data(dm, result, i, numEdges, 1); - *med2 = med; - numEdges++; - - med2->v1 = vert1; - med2->v2 = vert2; - - BLI_edgehash_insert(edges, med2->v1, med2->v2, NULL); - } - } - } - - maxFaces = dm->getNumFaces(dm); - mface = CDDM_get_faces(result); - for (i=0; i < maxFaces; i++) { - MFace inMF; - MFace *mf = &mface[numFaces]; - - dm->getFace(dm, i, &inMF); - - DM_copy_face_data(dm, result, i, numFaces, 1); - *mf = inMF; - - mf->v1 = indexMap[inMF.v1].new; - mf->v2 = indexMap[inMF.v2].new; - mf->v3 = indexMap[inMF.v3].new; - if(inMF.v4) - mf->v4 = indexMap[inMF.v4].new; + if(indexMap[inMED.v1].merge_final) { + med.v1 = calc_mapping(indexMap, indexMap[inMED.v1].merge, + count - 1); + } + if(indexMap[inMED.v2].merge_final) { + med.v2 = calc_mapping(indexMap, indexMap[inMED.v2].merge, + count - 1); + } + + if(med.v1 == med.v2) continue; + + /* XXX Unfortunately the calc_mapping returns sometimes numVerts... leads to bad crashes */ + if(med.v1 >= numVerts) + med.v1= numVerts-1; + if(med.v2 >= numVerts) + med.v2= numVerts-1; + + if (initFlags) { + med.flag |= ME_EDGEDRAW | ME_EDGERENDER; + } + + if(!BLI_edgehash_haskey(edges, med.v1, med.v2)) { + DM_copy_edge_data(dm, result, i, numEdges, 1); + medge[numEdges] = med; + numEdges++; + + BLI_edgehash_insert(edges, med.v1, med.v2, NULL); + } + + for(j = 1; j < count; j++) + { + vert1 = calc_mapping(indexMap, inMED.v1, j); + vert2 = calc_mapping(indexMap, inMED.v2, j); + + /* edge could collapse to single point after mapping */ + if(vert1 == vert2) continue; + + /* XXX Unfortunately the calc_mapping returns sometimes numVerts... leads to bad crashes */ + if(vert1 >= numVerts) + vert1= numVerts-1; + if(vert2 >= numVerts) + vert2= numVerts-1; + + /* avoid duplicate edges */ + if(!BLI_edgehash_haskey(edges, vert1, vert2)) { + med2 = &medge[numEdges]; + + DM_copy_edge_data(dm, result, i, numEdges, 1); + *med2 = med; + numEdges++; + + med2->v1 = vert1; + med2->v2 = vert2; + + BLI_edgehash_insert(edges, med2->v1, med2->v2, NULL); + } + } + } + + maxFaces = dm->getNumFaces(dm); + mface = CDDM_get_faces(result); + for (i=0; i < maxFaces; i++) { + MFace inMF; + MFace *mf = &mface[numFaces]; + + dm->getFace(dm, i, &inMF); + + DM_copy_face_data(dm, result, i, numFaces, 1); + *mf = inMF; + + mf->v1 = indexMap[inMF.v1].new; + mf->v2 = indexMap[inMF.v2].new; + mf->v3 = indexMap[inMF.v3].new; + if(inMF.v4) + mf->v4 = indexMap[inMF.v4].new; /* if vertices are to be merged with the final copies of their * merge targets, calculate that final copy */ - if(indexMap[inMF.v1].merge_final) - mf->v1 = calc_mapping(indexMap, indexMap[inMF.v1].merge, count-1); - if(indexMap[inMF.v2].merge_final) - mf->v2 = calc_mapping(indexMap, indexMap[inMF.v2].merge, count-1); - if(indexMap[inMF.v3].merge_final) - mf->v3 = calc_mapping(indexMap, indexMap[inMF.v3].merge, count-1); - if(inMF.v4 && indexMap[inMF.v4].merge_final) - mf->v4 = calc_mapping(indexMap, indexMap[inMF.v4].merge, count-1); - - if(test_index_face_maxvert(mf, &result->faceData, numFaces, inMF.v4?4:3, numVerts) < 3) - continue; - - numFaces++; - - /* if the face has fewer than 3 vertices, don't create it */ - if(mf->v3 == 0 || (mf->v1 && (mf->v1 == mf->v3 || mf->v1 == mf->v4))) { - numFaces--; - DM_free_face_data(result, numFaces, 1); - } - - for(j = 1; j < count; j++) - { - MFace *mf2 = &mface[numFaces]; - - DM_copy_face_data(dm, result, i, numFaces, 1); - *mf2 = *mf; - - mf2->v1 = calc_mapping(indexMap, inMF.v1, j); - mf2->v2 = calc_mapping(indexMap, inMF.v2, j); - mf2->v3 = calc_mapping(indexMap, inMF.v3, j); - if (inMF.v4) - mf2->v4 = calc_mapping(indexMap, inMF.v4, j); - - numFaces++; - - /* if the face has fewer than 3 vertices, don't create it */ - if(test_index_face_maxvert(mf2, &result->faceData, numFaces-1, inMF.v4?4:3, numVerts) < 3) { - numFaces--; - DM_free_face_data(result, numFaces, 1); - } - } - } - - /* add start and end caps */ - if(start_cap) { - float startoffset[4][4]; - MVert *cap_mvert; - MEdge *cap_medge; - MFace *cap_mface; - int *origindex; - int *vert_map; - int capVerts, capEdges, capFaces; - - capVerts = start_cap->getNumVerts(start_cap); - capEdges = start_cap->getNumEdges(start_cap); - capFaces = start_cap->getNumFaces(start_cap); - cap_mvert = start_cap->getVertArray(start_cap); - cap_medge = start_cap->getEdgeArray(start_cap); - cap_mface = start_cap->getFaceArray(start_cap); - - invert_m4_m4(startoffset, offset); - - vert_map = MEM_callocN(sizeof(*vert_map) * capVerts, - "arrayModifier_doArray vert_map"); - - origindex = result->getVertDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capVerts; i++) { - MVert *mv = &cap_mvert[i]; - short merged = 0; - - if(amd->flags & MOD_ARR_MERGE) { - float tmp_co[3]; - MVert *in_mv; - int j; - - copy_v3_v3(tmp_co, mv->co); - mul_m4_v3(startoffset, tmp_co); - - for(j = 0; j < maxVerts; j++) { - in_mv = &src_mvert[j]; - /* if this vert is within merge limit, merge */ - if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) { - vert_map[i] = calc_mapping(indexMap, j, 0); - merged = 1; - break; - } - } - } - - if(!merged) { - DM_copy_vert_data(start_cap, result, i, numVerts, 1); - mvert[numVerts] = *mv; - mul_m4_v3(startoffset, mvert[numVerts].co); - origindex[numVerts] = ORIGINDEX_NONE; - - vert_map[i] = numVerts; - - numVerts++; - } - } - origindex = result->getEdgeDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capEdges; i++) { - int v1, v2; - - v1 = vert_map[cap_medge[i].v1]; - v2 = vert_map[cap_medge[i].v2]; - - if(!BLI_edgehash_haskey(edges, v1, v2)) { - DM_copy_edge_data(start_cap, result, i, numEdges, 1); - medge[numEdges] = cap_medge[i]; - medge[numEdges].v1 = v1; - medge[numEdges].v2 = v2; - origindex[numEdges] = ORIGINDEX_NONE; - - numEdges++; - } - } - origindex = result->getFaceDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capFaces; i++) { - DM_copy_face_data(start_cap, result, i, numFaces, 1); - mface[numFaces] = cap_mface[i]; - mface[numFaces].v1 = vert_map[mface[numFaces].v1]; - mface[numFaces].v2 = vert_map[mface[numFaces].v2]; - mface[numFaces].v3 = vert_map[mface[numFaces].v3]; - if(mface[numFaces].v4) { - mface[numFaces].v4 = vert_map[mface[numFaces].v4]; - - test_index_face_maxvert(&mface[numFaces], &result->faceData, - numFaces, 4, numVerts); - } - else - { - test_index_face(&mface[numFaces], &result->faceData, - numFaces, 3); - } - - origindex[numFaces] = ORIGINDEX_NONE; - - numFaces++; - } - - MEM_freeN(vert_map); - start_cap->release(start_cap); - } - - if(end_cap) { - float endoffset[4][4]; - MVert *cap_mvert; - MEdge *cap_medge; - MFace *cap_mface; - int *origindex; - int *vert_map; - int capVerts, capEdges, capFaces; - - capVerts = end_cap->getNumVerts(end_cap); - capEdges = end_cap->getNumEdges(end_cap); - capFaces = end_cap->getNumFaces(end_cap); - cap_mvert = end_cap->getVertArray(end_cap); - cap_medge = end_cap->getEdgeArray(end_cap); - cap_mface = end_cap->getFaceArray(end_cap); - - mul_m4_m4m4(endoffset, final_offset, offset); - - vert_map = MEM_callocN(sizeof(*vert_map) * capVerts, - "arrayModifier_doArray vert_map"); - - origindex = result->getVertDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capVerts; i++) { - MVert *mv = &cap_mvert[i]; - short merged = 0; - - if(amd->flags & MOD_ARR_MERGE) { - float tmp_co[3]; - MVert *in_mv; - int j; - - copy_v3_v3(tmp_co, mv->co); - mul_m4_v3(offset, tmp_co); - - for(j = 0; j < maxVerts; j++) { - in_mv = &src_mvert[j]; - /* if this vert is within merge limit, merge */ - if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) { - vert_map[i] = calc_mapping(indexMap, j, count - 1); - merged = 1; - break; - } - } - } - - if(!merged) { - DM_copy_vert_data(end_cap, result, i, numVerts, 1); - mvert[numVerts] = *mv; - mul_m4_v3(endoffset, mvert[numVerts].co); - origindex[numVerts] = ORIGINDEX_NONE; - - vert_map[i] = numVerts; - - numVerts++; - } - } - origindex = result->getEdgeDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capEdges; i++) { - int v1, v2; - - v1 = vert_map[cap_medge[i].v1]; - v2 = vert_map[cap_medge[i].v2]; - - if(!BLI_edgehash_haskey(edges, v1, v2)) { - DM_copy_edge_data(end_cap, result, i, numEdges, 1); - medge[numEdges] = cap_medge[i]; - medge[numEdges].v1 = v1; - medge[numEdges].v2 = v2; - origindex[numEdges] = ORIGINDEX_NONE; - - numEdges++; - } - } - origindex = result->getFaceDataArray(result, CD_ORIGINDEX); - for(i = 0; i < capFaces; i++) { - DM_copy_face_data(end_cap, result, i, numFaces, 1); - mface[numFaces] = cap_mface[i]; - mface[numFaces].v1 = vert_map[mface[numFaces].v1]; - mface[numFaces].v2 = vert_map[mface[numFaces].v2]; - mface[numFaces].v3 = vert_map[mface[numFaces].v3]; - if(mface[numFaces].v4) { - mface[numFaces].v4 = vert_map[mface[numFaces].v4]; - - test_index_face(&mface[numFaces], &result->faceData, - numFaces, 4); - } - else - { - test_index_face(&mface[numFaces], &result->faceData, - numFaces, 3); - } - origindex[numFaces] = ORIGINDEX_NONE; - - numFaces++; - } - - MEM_freeN(vert_map); - end_cap->release(end_cap); - } - - BLI_edgehash_free(edges, NULL); - MEM_freeN(indexMap); - - CDDM_lower_num_verts(result, numVerts); - CDDM_lower_num_edges(result, numEdges); - CDDM_lower_num_faces(result, numFaces); - - return result; + if(indexMap[inMF.v1].merge_final) + mf->v1 = calc_mapping(indexMap, indexMap[inMF.v1].merge, count-1); + if(indexMap[inMF.v2].merge_final) + mf->v2 = calc_mapping(indexMap, indexMap[inMF.v2].merge, count-1); + if(indexMap[inMF.v3].merge_final) + mf->v3 = calc_mapping(indexMap, indexMap[inMF.v3].merge, count-1); + if(inMF.v4 && indexMap[inMF.v4].merge_final) + mf->v4 = calc_mapping(indexMap, indexMap[inMF.v4].merge, count-1); + + if(test_index_face_maxvert(mf, &result->faceData, numFaces, inMF.v4?4:3, numVerts) < 3) + continue; + + numFaces++; + + /* if the face has fewer than 3 vertices, don't create it */ + if(mf->v3 == 0 || (mf->v1 && (mf->v1 == mf->v3 || mf->v1 == mf->v4))) { + numFaces--; + DM_free_face_data(result, numFaces, 1); + } + + for(j = 1; j < count; j++) + { + MFace *mf2 = &mface[numFaces]; + + DM_copy_face_data(dm, result, i, numFaces, 1); + *mf2 = *mf; + + mf2->v1 = calc_mapping(indexMap, inMF.v1, j); + mf2->v2 = calc_mapping(indexMap, inMF.v2, j); + mf2->v3 = calc_mapping(indexMap, inMF.v3, j); + if (inMF.v4) + mf2->v4 = calc_mapping(indexMap, inMF.v4, j); + + numFaces++; + + /* if the face has fewer than 3 vertices, don't create it */ + if(test_index_face_maxvert(mf2, &result->faceData, numFaces-1, inMF.v4?4:3, numVerts) < 3) { + numFaces--; + DM_free_face_data(result, numFaces, 1); + } + } + } + + /* add start and end caps */ + if(start_cap) { + float startoffset[4][4]; + MVert *cap_mvert; + MEdge *cap_medge; + MFace *cap_mface; + int *origindex; + int *vert_map; + int capVerts, capEdges, capFaces; + + capVerts = start_cap->getNumVerts(start_cap); + capEdges = start_cap->getNumEdges(start_cap); + capFaces = start_cap->getNumFaces(start_cap); + cap_mvert = start_cap->getVertArray(start_cap); + cap_medge = start_cap->getEdgeArray(start_cap); + cap_mface = start_cap->getFaceArray(start_cap); + + invert_m4_m4(startoffset, offset); + + vert_map = MEM_callocN(sizeof(*vert_map) * capVerts, + "arrayModifier_doArray vert_map"); + + origindex = result->getVertDataArray(result, CD_ORIGINDEX); + for(i = 0; i < capVerts; i++) { + MVert *mv = &cap_mvert[i]; + short merged = 0; + + if(amd->flags & MOD_ARR_MERGE) { + float tmp_co[3]; + MVert *in_mv; + int j; + + copy_v3_v3(tmp_co, mv->co); + mul_m4_v3(startoffset, tmp_co); + + for(j = 0; j < maxVerts; j++) { + in_mv = &src_mvert[j]; + /* if this vert is within merge limit, merge */ + if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) { + vert_map[i] = calc_mapping(indexMap, j, 0); + merged = 1; + break; + } + } + } + + if(!merged) { + DM_copy_vert_data(start_cap, result, i, numVerts, 1); + mvert[numVerts] = *mv; + mul_m4_v3(startoffset, mvert[numVerts].co); + origindex[numVerts] = ORIGINDEX_NONE; + + vert_map[i] = numVerts; + + numVerts++; + } + } + origindex = result->getEdgeDataArray(result, CD_ORIGINDEX); + for(i = 0; i < capEdges; i++) { + int v1, v2; + + v1 = vert_map[cap_medge[i].v1]; + v2 = vert_map[cap_medge[i].v2]; + + if(!BLI_edgehash_haskey(edges, v1, v2)) { + DM_copy_edge_data(start_cap, result, i, numEdges, 1); + medge[numEdges] = cap_medge[i]; + medge[numEdges].v1 = v1; + medge[numEdges].v2 = v2; + origindex[numEdges] = ORIGINDEX_NONE; + + numEdges++; + } + } + origindex = result->getFaceDataArray(result, CD_ORIGINDEX); + for(i = 0; i < capFaces; i++) { + DM_copy_face_data(start_cap, result, i, numFaces, 1); + mface[numFaces] = cap_mface[i]; + mface[numFaces].v1 = vert_map[mface[numFaces].v1]; + mface[numFaces].v2 = vert_map[mface[numFaces].v2]; + mface[numFaces].v3 = vert_map[mface[numFaces].v3]; + if(mface[numFaces].v4) { + mface[numFaces].v4 = vert_map[mface[numFaces].v4]; + + test_index_face_maxvert(&mface[numFaces], &result->faceData, + numFaces, 4, numVerts); + } + else + { + test_index_face(&mface[numFaces], &result->faceData, + numFaces, 3); + } + + origindex[numFaces] = ORIGINDEX_NONE; + + numFaces++; + } + + MEM_freeN(vert_map); + start_cap->release(start_cap); + } + + if(end_cap) { + float endoffset[4][4]; + MVert *cap_mvert; + MEdge *cap_medge; + MFace *cap_mface; + int *origindex; + int *vert_map; + int capVerts, capEdges, capFaces; + + capVerts = end_cap->getNumVerts(end_cap); + capEdges = end_cap->getNumEdges(end_cap); + capFaces = end_cap->getNumFaces(end_cap); + cap_mvert = end_cap->getVertArray(end_cap); + cap_medge = end_cap->getEdgeArray(end_cap); + cap_mface = end_cap->getFaceArray(end_cap); + + mul_m4_m4m4(endoffset, final_offset, offset); + + vert_map = MEM_callocN(sizeof(*vert_map) * capVerts, + "arrayModifier_doArray vert_map"); + + origindex = result->getVertDataArray(result, CD_ORIGINDEX); + for(i = 0; i < capVerts; i++) { + MVert *mv = &cap_mvert[i]; + short merged = 0; + + if(amd->flags & MOD_ARR_MERGE) { + float tmp_co[3]; + MVert *in_mv; + int j; + + copy_v3_v3(tmp_co, mv->co); + mul_m4_v3(offset, tmp_co); + + for(j = 0; j < maxVerts; j++) { + in_mv = &src_mvert[j]; + /* if this vert is within merge limit, merge */ + if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) { + vert_map[i] = calc_mapping(indexMap, j, count - 1); + merged = 1; + break; + } + } + } + + if(!merged) { + DM_copy_vert_data(end_cap, result, i, numVerts, 1); + mvert[numVerts] = *mv; + mul_m4_v3(endoffset, mvert[numVerts].co); + origindex[numVerts] = ORIGINDEX_NONE; + + vert_map[i] = numVerts; + + numVerts++; + } + } + origindex = result->getEdgeDataArray(result, CD_ORIGINDEX); + for(i = 0; i < capEdges; i++) { + int v1, v2; + + v1 = vert_map[cap_medge[i].v1]; + v2 = vert_map[cap_medge[i].v2]; + + if(!BLI_edgehash_haskey(edges, v1, v2)) { + DM_copy_edge_data(end_cap, result, i, numEdges, 1); + medge[numEdges] = cap_medge[i]; + medge[numEdges].v1 = v1; + medge[numEdges].v2 = v2; + origindex[numEdges] = ORIGINDEX_NONE; + + numEdges++; + } + } + origindex = result->getFaceDataArray(result, CD_ORIGINDEX); + for(i = 0; i < capFaces; i++) { + DM_copy_face_data(end_cap, result, i, numFaces, 1); + mface[numFaces] = cap_mface[i]; + mface[numFaces].v1 = vert_map[mface[numFaces].v1]; + mface[numFaces].v2 = vert_map[mface[numFaces].v2]; + mface[numFaces].v3 = vert_map[mface[numFaces].v3]; + if(mface[numFaces].v4) { + mface[numFaces].v4 = vert_map[mface[numFaces].v4]; + + test_index_face(&mface[numFaces], &result->faceData, + numFaces, 4); + } + else + { + test_index_face(&mface[numFaces], &result->faceData, + numFaces, 3); + } + origindex[numFaces] = ORIGINDEX_NONE; + + numFaces++; + } + + MEM_freeN(vert_map); + end_cap->release(end_cap); + } + + BLI_edgehash_free(edges, NULL); + MEM_freeN(indexMap); + + CDDM_lower_num_verts(result, numVerts); + CDDM_lower_num_edges(result, numEdges); + CDDM_lower_num_faces(result, numFaces); + + return result; } static DerivedMesh *applyModifier(ModifierData *md, Object *ob, |