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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/modifiers/intern/MOD_array.c')
-rw-r--r--source/blender/modifiers/intern/MOD_array.c715
1 files changed, 219 insertions, 496 deletions
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index ce052b2c1bd..01dc978bc25 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -28,17 +28,12 @@
*
*/
-/** \file blender/modifiers/intern/MOD_array.c
- * \ingroup modifiers
- */
-
-
/* Array modifier: duplicates the object multiple times along an axis */
#include "MEM_guardedalloc.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_math.h"
#include "BLI_ghash.h"
#include "BLI_edgehash.h"
@@ -51,10 +46,13 @@
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_tessmesh.h"
#include "depsgraph_private.h"
-#include "MOD_util.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
static void initData(ModifierData *md)
{
@@ -107,8 +105,8 @@ static void foreachObjectLink(
walk(userData, ob, &amd->offset_ob);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Scene *UNUSED(scene), Object *UNUSED(ob), DagNode *obNode)
+static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene),
+ Object *UNUSED(ob), DagNode *obNode)
{
ArrayModifierData *amd = (ArrayModifierData*) md;
@@ -157,28 +155,116 @@ static float vertarray_size(MVert *mvert, int numVerts, int axis)
return max_co - min_co;
}
-/* XXX This function fixes bad merging code, in some cases removing vertices creates indices > maxvert */
-
-static int test_index_face_maxvert(MFace *mface, CustomData *fdata, int mfindex, int nr, int maxvert)
+/* finds the best possible flipped name. For renaming; check for unique names afterwards */
+/* if strip_number: removes number extensions */
+void vertgroup_flip_name (char *name, int strip_number)
{
- if(mface->v1 >= maxvert) {
- // printf("bad index in array\n");
- mface->v1= maxvert - 1;
+ int len;
+ char prefix[128]={""}; /* The part before the facing */
+ char suffix[128]={""}; /* The part after the facing */
+ char replace[128]={""}; /* The replacement string */
+ char number[128]={""}; /* The number extension string */
+ char *index=NULL;
+
+ len= strlen(name);
+ if(len<3) return; // we don't do names like .R or .L
+
+ /* We first check the case with a .### extension, let's find the last period */
+ if(isdigit(name[len-1])) {
+ index= strrchr(name, '.'); // last occurrance
+ if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
+ if(strip_number==0)
+ strcpy(number, index);
+ *index= 0;
+ len= strlen(name);
+ }
}
- if(mface->v2 >= maxvert) {
- // printf("bad index in array\n");
- mface->v2= maxvert - 1;
+
+ strcpy (prefix, name);
+
+#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_')
+
+ /* first case; separator . - _ with extensions r R l L */
+ if( IS_SEPARATOR(name[len-2]) ) {
+ switch(name[len-1]) {
+ case 'l':
+ prefix[len-1]= 0;
+ strcpy(replace, "r");
+ break;
+ case 'r':
+ prefix[len-1]= 0;
+ strcpy(replace, "l");
+ break;
+ case 'L':
+ prefix[len-1]= 0;
+ strcpy(replace, "R");
+ break;
+ case 'R':
+ prefix[len-1]= 0;
+ strcpy(replace, "L");
+ break;
+ }
}
- if(mface->v3 >= maxvert) {
- // printf("bad index in array\n");
- mface->v3= maxvert - 1;
+ /* case; beginning with r R l L , with separator after it */
+ else if( IS_SEPARATOR(name[1]) ) {
+ switch(name[0]) {
+ case 'l':
+ strcpy(replace, "r");
+ strcpy(suffix, name+1);
+ prefix[0]= 0;
+ break;
+ case 'r':
+ strcpy(replace, "l");
+ strcpy(suffix, name+1);
+ prefix[0]= 0;
+ break;
+ case 'L':
+ strcpy(replace, "R");
+ strcpy(suffix, name+1);
+ prefix[0]= 0;
+ break;
+ case 'R':
+ strcpy(replace, "L");
+ strcpy(suffix, name+1);
+ prefix[0]= 0;
+ break;
+ }
}
- if(mface->v4 >= maxvert) {
- // printf("bad index in array\n");
- mface->v4= maxvert - 1;
+ else if(len > 5) {
+ /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
+ index = BLI_strcasestr(prefix, "right");
+ if (index==prefix || index==prefix+len-5) {
+ if(index[0]=='r')
+ strcpy (replace, "left");
+ else {
+ if(index[1]=='I')
+ strcpy (replace, "LEFT");
+ else
+ strcpy (replace, "Left");
+ }
+ *index= 0;
+ strcpy (suffix, index+5);
+ }
+ else {
+ index = BLI_strcasestr(prefix, "left");
+ if (index==prefix || index==prefix+len-4) {
+ if(index[0]=='l')
+ strcpy (replace, "right");
+ else {
+ if(index[1]=='E')
+ strcpy (replace, "RIGHT");
+ else
+ strcpy (replace, "Right");
+ }
+ *index= 0;
+ strcpy (suffix, index+4);
+ }
+ }
}
-
- return test_index_face(mface, fdata, mfindex, nr);
+
+#undef IS_SEPARATOR
+
+ sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
}
typedef struct IndexMapEntry {
@@ -220,45 +306,34 @@ static int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum)
}
static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
- struct Scene *scene, Object *ob, DerivedMesh *dm,
- int initFlags)
+ Scene *scene, Object *ob, DerivedMesh *dm,
+ int UNUSED(initFlags))
{
- int i, j;
+ DerivedMesh *cddm = dm; //copying shouldn't be necassary here, as all modifiers return CDDM's
+ BMEditMesh *em = CDDM_To_BMesh(ob, cddm, NULL);
+ BMOperator op, oldop, weldop;
+ int i, j, indexLen;
/* offset matrix */
float offset[4][4];
- float final_offset[4][4];
- float tmp_mat[4][4];
float length = amd->length;
- int count = amd->count;
- int numVerts, numEdges, numFaces;
- int maxVerts, maxEdges, maxFaces;
- int finalVerts, finalEdges, finalFaces;
- DerivedMesh *result, *start_cap = NULL, *end_cap = NULL;
- MVert *mvert, *src_mvert;
- MEdge *medge;
- MFace *mface;
-
- IndexMapEntry *indexMap;
-
- EdgeHash *edges;
+ int count = amd->count, maxVerts;
+ int *indexMap = NULL;
+ DerivedMesh *start_cap = NULL, *end_cap = NULL;
+ MVert *src_mvert;
/* need to avoid infinite recursion here */
if(amd->start_cap && amd->start_cap != ob)
- start_cap = amd->start_cap->derivedFinal;
+ start_cap = mesh_get_derived_final(scene, amd->start_cap, CD_MASK_MESH);
if(amd->end_cap && amd->end_cap != ob)
- end_cap = amd->end_cap->derivedFinal;
+ end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH);
unit_m4(offset);
- indexMap = MEM_callocN(sizeof(*indexMap) * dm->getNumVerts(dm),
- "indexmap");
-
- src_mvert = dm->getVertArray(dm);
-
- maxVerts = dm->getNumVerts(dm);
+ src_mvert = cddm->getVertArray(dm);
+ maxVerts = cddm->getNumVerts(dm);
if(amd->offset_type & MOD_ARR_OFF_CONST)
- add_v3_v3(offset[3], amd->offset);
+ add_v3_v3v3(offset[3], offset[3], amd->offset);
if(amd->offset_type & MOD_ARR_OFF_RELATIVE) {
for(j = 0; j < 3; j++)
offset[3][j] += amd->scale[j] * vertarray_size(src_mvert,
@@ -285,10 +360,10 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
if(cu) {
float tmp_mat[3][3];
float scale;
-
+
object_to_mat3(amd->curve_ob, tmp_mat);
scale = mat3_to_scale(tmp_mat);
-
+
if(!cu->path) {
cu->flag |= CU_PATH; // needed for path & bevlist
makeDispListCurveTypes(scene, amd->curve_ob, 0);
@@ -301,8 +376,9 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
/* calculate the maximum number of copies which will fit within the
prescribed length */
if(amd->fit_type == MOD_ARR_FITLENGTH
- || amd->fit_type == MOD_ARR_FITCURVE) {
- float dist = sqrt(dot_v3v3(offset[3], offset[3]));
+ || amd->fit_type == MOD_ARR_FITCURVE)
+ {
+ float dist = sqrt(INPR(offset[3], offset[3]));
if(dist > 1e-6f)
/* this gives length = first copy start to last copy end
@@ -316,484 +392,131 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
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);
-
- /* Attempts to merge verts from one duplicate with verts from the
- * next duplicate which are closer than amd->merge_dist.
- * Only the first such vert pair is merged.
- * 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;
- }
+ /* BMESH_TODO: bumping up the stack level avoids computing the normals
+ after every top-level operator execution (and this modifier has the
+ potential to execute a *lot* of top-level BMOps. There should be a
+ cleaner way to do this. One possibility: a "mirror" BMOp would
+ certainly help by compressing it all into one top-level BMOp that
+ executes a lot of second-level BMOps. */
+ BMO_push(em->bm, NULL);
+ bmesh_begin_edit(em->bm, 0);
+
+ BMO_Init_Op(&weldop, "weldverts");
+ BMO_InitOpf(em->bm, &op, "dupe geom=%avef");
+ oldop = op;
+ for (j=0; j < count - 1; j++) {
+ BMVert *v, *v2;
+ BMOpSlot *s1;
+ BMOpSlot *s2;
+
+ BMO_InitOpf(em->bm, &op, "dupe geom=%s", &oldop, j==0 ? "geom" : "newout");
+ BMO_Exec_Op(em->bm, &op);
+
+ s1 = BMO_GetSlot(&op, "geom");
+ s2 = BMO_GetSlot(&op, "newout");
+
+ BMO_CallOpf(em->bm, "transform mat=%m4 verts=%s", offset, &op, "newout");
+
+ #define _E(s, i) ((BMVert**)(s)->data.buf)[i]
+
+ /*calculate merge mapping*/
+ if (j == 0) {
+ BMOperator findop;
+ BMOIter oiter;
+ BMVert *v, *v2;
+ BMHeader *h;
+
+ BMO_InitOpf(em->bm, &findop,
+ "finddoubles verts=%av dist=%f keepverts=%s",
+ amd->merge_dist, &op, "geom");
+
+ i = 0;
+ BMO_ITER(h, &oiter, em->bm, &op, "geom", BM_ALL) {
+ BM_SetIndex(h, i);
+ i++;
}
- }
- /* 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);
+ BMO_ITER(h, &oiter, em->bm, &op, "newout", BM_ALL) {
+ BM_SetIndex(h, i);
+ i++;
}
- } 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);
- }
- }
- /* make a hashtable so we can avoid duplicate edges from merging */
- edges = BLI_edgehash_new();
+ BMO_Exec_Op(em->bm, &findop);
- maxEdges = dm->getNumEdges(dm);
- medge = CDDM_get_edges(result);
- for(i = 0; i < maxEdges; i++) {
- MEdge inMED;
- MEdge med;
- MEdge *med2;
- int vert1, vert2;
+ indexLen = i;
+ indexMap = MEM_callocN(sizeof(int)*indexLen, "indexMap");
- dm->getEdge(dm, i, &inMED);
-
- 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;
- }
+ /*element type argument doesn't do anything here*/
+ BMO_ITER(v, &oiter, em->bm, &findop, "targetmapout", 0) {
+ v2 = BMO_IterMapValp(&oiter);
- 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);
+ indexMap[BM_GetIndex(v)] = BM_GetIndex(v2)+1;
}
- }
- }
-
- 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);
+ BMO_Finish_Op(em->bm, &findop);
}
- 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;
+ /*generate merge mappping using index map. we do this by using the
+ operator slots as lookup arrays.*/
+ #define E(i) (i) < s1->len ? _E(s1, i) : _E(s2, (i)-s1->len)
- numVerts++;
- }
- }
- origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
- for(i = 0; i < capEdges; i++) {
- int v1, v2;
+ for (i=0; i<indexLen; i++) {
+ if (!indexMap[i]) continue;
- v1 = vert_map[cap_medge[i].v1];
- v2 = vert_map[cap_medge[i].v2];
+ v = E(i);
+ v2 = E(indexMap[i]-1);
- 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++;
- }
+ BMO_Insert_MapPointer(em->bm, &weldop, "targetmap", v, v2);
}
- 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++;
- }
+ #undef E
+ #undef _E
- MEM_freeN(vert_map);
- start_cap->release(start_cap);
+ BMO_Finish_Op(em->bm, &oldop);
+ oldop = op;
}
- 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;
+ if (j > 0) BMO_Finish_Op(em->bm, &op);
- vert_map[i] = numVerts;
+ if (amd->flags & MOD_ARR_MERGE)
+ BMO_Exec_Op(em->bm, &weldop);
- numVerts++;
- }
- }
- origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
- for(i = 0; i < capEdges; i++) {
- int v1, v2;
+ BMO_Finish_Op(em->bm, &weldop);
- v1 = vert_map[cap_medge[i].v1];
- v2 = vert_map[cap_medge[i].v2];
+ /* Bump the stack level back down to match the adjustment up above */
+ bmesh_end_edit(em->bm, 0);
+ BMO_pop(em->bm);
- 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;
+ BMEdit_RecalcTesselation(em);
+ cddm = CDDM_from_BMEditMesh(em, NULL, 0);
- numFaces++;
- }
-
- MEM_freeN(vert_map);
- end_cap->release(end_cap);
- }
-
- BLI_edgehash_free(edges, NULL);
+ BMEdit_Free(em);
+ MEM_freeN(em);
MEM_freeN(indexMap);
- CDDM_lower_num_verts(result, numVerts);
- CDDM_lower_num_edges(result, numEdges);
- CDDM_lower_num_faces(result, numFaces);
-
- return result;
+ return cddm;
}
-static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
- DerivedMesh *dm,
- int UNUSED(useRenderParams),
- int UNUSED(isFinalCalc))
+static DerivedMesh *applyModifier(
+ ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ int UNUSED(useRenderParams), int UNUSED(isFinalCalc))
{
DerivedMesh *result;
ArrayModifierData *amd = (ArrayModifierData*) md;
- result = arrayModifier_doArray(amd, md->scene, ob, dm, 0);
+ result = arrayModifier_doArray(amd, md->scene, ob, derivedData, 0);
- if(result != dm)
- CDDM_calc_normals(result);
+ //if(result != derivedData)
+ // CDDM_calc_normals(result);
return result;
}
-static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
- struct EditMesh *UNUSED(editData),
- DerivedMesh *dm)
+static DerivedMesh *applyModifierEM(
+ ModifierData *md, Object *ob, struct BMEditMesh *UNUSED(editData),
+ DerivedMesh *derivedData)
{
- return applyModifier(md, ob, dm, 0, 1);
+ return applyModifier(md, ob, derivedData, 0, 1);
}