Example #1
0
static DerivedMesh *cloth_to_triangles(DerivedMesh *dm)
{
	DerivedMesh *result = NULL;
	unsigned int i = 0, j = 0;
	unsigned int quads = 0, numfaces = dm->getNumTessFaces(dm);
	MFace *mface = dm->getTessFaceArray(dm);
	MFace *mface2 = NULL;

	/* calc faces */
	for (i = 0; i < numfaces; i++) {
		if (mface[i].v4) {
			quads++;
		}
	}
		
	result = CDDM_from_template(dm, dm->getNumVerts(dm), 0, numfaces + quads, 0, 0);

	DM_copy_vert_data(dm, result, 0, 0, dm->getNumVerts(dm));
	DM_copy_tessface_data(dm, result, 0, 0, numfaces);

	DM_ensure_tessface(result);
	mface2 = result->getTessFaceArray(result);

	for (i = 0, j = numfaces; i < numfaces; i++) {
		// DG TODO: is this necessary?
		mface2[i].v1 = mface[i].v1;
		mface2[i].v2 = mface[i].v2;
		mface2[i].v3 = mface[i].v3;

		mface2[i].v4 = 0;
		//test_index_face(&mface2[i], &result->faceData, i, 3);

		if (mface[i].v4) {
			DM_copy_tessface_data(dm, result, i, j, 1);

			mface2[j].v1 = mface[i].v1;
			mface2[j].v2 = mface[i].v3;
			mface2[j].v3 = mface[i].v4;
			mface2[j].v4 = 0;
			//test_index_face(&mface2[j], &result->faceData, j, 3);

			j++;
		}
	}

	CDDM_calc_edges_tessface(result);
	CDDM_tessfaces_to_faces(result); /* builds ngon faces from tess (mface) faces */

	return result;
}
static DerivedMesh *explodeMesh(ExplodeModifierData *emd,
                                ParticleSystemModifierData *psmd, Scene *scene, Object *ob,
                                DerivedMesh *to_explode)
{
	DerivedMesh *explode, *dm = to_explode;
	MFace *mf = NULL, *mface;
	/* ParticleSettings *part=psmd->psys->part; */ /* UNUSED */
	ParticleSimulationData sim = {NULL};
	ParticleData *pa = NULL, *pars = psmd->psys->particles;
	ParticleKey state, birth;
	EdgeHash *vertpahash;
	EdgeHashIterator *ehi;
	float *vertco = NULL, imat[4][4];
	float rot[4];
	float cfra;
	/* float timestep; */
	const int *facepa = emd->facepa;
	int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0;
	int i, v, u;
	unsigned int ed_v1, ed_v2, mindex = 0;
	MTFace *mtface = NULL, *mtf;

	totface = dm->getNumTessFaces(dm);
	totvert = dm->getNumVerts(dm);
	mface = dm->getTessFaceArray(dm);
	totpart = psmd->psys->totpart;

	sim.scene = scene;
	sim.ob = ob;
	sim.psys = psmd->psys;
	sim.psmd = psmd;

	/* timestep = psys_get_timestep(&sim); */

	cfra = BKE_scene_frame_get(scene);

	/* hash table for vertice <-> particle relations */
	vertpahash = BLI_edgehash_new(__func__);

	for (i = 0; i < totface; i++) {
		if (facepa[i] != totpart) {
			pa = pars + facepa[i];

			if ((pa->alive == PARS_UNBORN && (emd->flag & eExplodeFlag_Unborn) == 0) ||
			    (pa->alive == PARS_ALIVE && (emd->flag & eExplodeFlag_Alive) == 0) ||
			    (pa->alive == PARS_DEAD && (emd->flag & eExplodeFlag_Dead) == 0))
			{
				delface++;
				continue;
			}
		}

		/* do mindex + totvert to ensure the vertex index to be the first
		 * with BLI_edgehashIterator_getKey */
		if (facepa[i] == totpart || cfra < (pars + facepa[i])->time)
			mindex = totvert + totpart;
		else 
			mindex = totvert + facepa[i];

		mf = &mface[i];

		/* set face vertices to exist in particle group */
		BLI_edgehash_reinsert(vertpahash, mf->v1, mindex, NULL);
		BLI_edgehash_reinsert(vertpahash, mf->v2, mindex, NULL);
		BLI_edgehash_reinsert(vertpahash, mf->v3, mindex, NULL);
		if (mf->v4)
			BLI_edgehash_reinsert(vertpahash, mf->v4, mindex, NULL);
	}

	/* make new vertice indexes & count total vertices after duplication */
	ehi = BLI_edgehashIterator_new(vertpahash);
	for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
		BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totdup));
		totdup++;
	}
	BLI_edgehashIterator_free(ehi);

	/* the final duplicated vertices */
	explode = CDDM_from_template_ex(dm, totdup, 0, totface - delface, 0, 0, CD_MASK_DERIVEDMESH | CD_MASK_FACECORNERS);
	mtface = CustomData_get_layer_named(&explode->faceData, CD_MTFACE, emd->uvname);
	/*dupvert = CDDM_get_verts(explode);*/

	/* getting back to object space */
	invert_m4_m4(imat, ob->obmat);

	psmd->psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);

	/* duplicate & displace vertices */
	ehi = BLI_edgehashIterator_new(vertpahash);
	for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
		MVert source;
		MVert *dest;

		/* get particle + vertex from hash */
		BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2);
		ed_v2 -= totvert;
		v = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));

		dm->getVert(dm, ed_v1, &source);
		dest = CDDM_get_vert(explode, v);

		DM_copy_vert_data(dm, explode, ed_v1, v, 1);
		*dest = source;

		if (ed_v2 != totpart) {
			/* get particle */
			pa = pars + ed_v2;

			psys_get_birth_coords(&sim, pa, &birth, 0, 0);

			state.time = cfra;
			psys_get_particle_state(&sim, ed_v2, &state, 1);

			vertco = CDDM_get_vert(explode, v)->co;
			mul_m4_v3(ob->obmat, vertco);

			sub_v3_v3(vertco, birth.co);

			/* apply rotation, size & location */
			sub_qt_qtqt(rot, state.rot, birth.rot);
			mul_qt_v3(rot, vertco);

			if (emd->flag & eExplodeFlag_PaSize)
				mul_v3_fl(vertco, pa->size);

			add_v3_v3(vertco, state.co);

			mul_m4_v3(imat, vertco);
		}
	}
	BLI_edgehashIterator_free(ehi);

	/*map new vertices to faces*/
	for (i = 0, u = 0; i < totface; i++) {
		MFace source;
		int orig_v4;

		if (facepa[i] != totpart) {
			pa = pars + facepa[i];

			if (pa->alive == PARS_UNBORN && (emd->flag & eExplodeFlag_Unborn) == 0) continue;
			if (pa->alive == PARS_ALIVE && (emd->flag & eExplodeFlag_Alive) == 0) continue;
			if (pa->alive == PARS_DEAD && (emd->flag & eExplodeFlag_Dead) == 0) continue;
		}

		dm->getTessFace(dm, i, &source);
		mf = CDDM_get_tessface(explode, u);
		
		orig_v4 = source.v4;

		if (facepa[i] != totpart && cfra < pa->time)
			mindex = totvert + totpart;
		else 
			mindex = totvert + facepa[i];

		source.v1 = edgecut_get(vertpahash, source.v1, mindex);
		source.v2 = edgecut_get(vertpahash, source.v2, mindex);
		source.v3 = edgecut_get(vertpahash, source.v3, mindex);
		if (source.v4)
			source.v4 = edgecut_get(vertpahash, source.v4, mindex);

		DM_copy_tessface_data(dm, explode, i, u, 1);

		*mf = source;

		/* override uv channel for particle age */
		if (mtface) {
			float age = (cfra - pa->time) / pa->lifetime;
			/* Clamp to this range to avoid flipping to the other side of the coordinates. */
			CLAMP(age, 0.001f, 0.999f);

			mtf = mtface + u;

			mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = age;
			mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = 0.5f;
		}

		test_index_face(mf, &explode->faceData, u, (orig_v4 ? 4 : 3));
		u++;
	}

	/* cleanup */
	BLI_edgehash_free(vertpahash, NULL);

	/* finalization */
	CDDM_calc_edges_tessface(explode);
	CDDM_tessfaces_to_faces(explode);
	explode->dirty |= DM_DIRTY_NORMALS;

	if (psmd->psys->lattice_deform_data) {
		end_latt_deform(psmd->psys->lattice_deform_data);
		psmd->psys->lattice_deform_data = NULL;
	}

	return explode;
}
static DerivedMesh *cutEdges(ExplodeModifierData *emd, DerivedMesh *dm)
{
	DerivedMesh *splitdm;
	MFace *mf = NULL, *df1 = NULL;
	MFace *mface = dm->getTessFaceArray(dm);
	MVert *dupve, *mv;
	EdgeHash *edgehash;
	EdgeHashIterator *ehi;
	int totvert = dm->getNumVerts(dm);
	int totface = dm->getNumTessFaces(dm);

	int *facesplit = MEM_callocN(sizeof(int) * totface, "explode_facesplit");
	int *vertpa = MEM_callocN(sizeof(int) * totvert, "explode_vertpa2");
	int *facepa = emd->facepa;
	int *fs, totesplit = 0, totfsplit = 0, curdupface = 0;
	int i, v1, v2, v3, v4, esplit,
	    v[4]  = {0, 0, 0, 0}, /* To quite gcc barking... */
	    uv[4] = {0, 0, 0, 0}; /* To quite gcc barking... */
	int numlayer;
	unsigned int ed_v1, ed_v2;

	edgehash = BLI_edgehash_new(__func__);

	/* recreate vertpa from facepa calculation */
	for (i = 0, mf = mface; i < totface; i++, mf++) {
		vertpa[mf->v1] = facepa[i];
		vertpa[mf->v2] = facepa[i];
		vertpa[mf->v3] = facepa[i];
		if (mf->v4)
			vertpa[mf->v4] = facepa[i];
	}

	/* mark edges for splitting and how to split faces */
	for (i = 0, mf = mface, fs = facesplit; i < totface; i++, mf++, fs++) {
		v1 = vertpa[mf->v1];
		v2 = vertpa[mf->v2];
		v3 = vertpa[mf->v3];

		if (v1 != v2) {
			BLI_edgehash_reinsert(edgehash, mf->v1, mf->v2, NULL);
			(*fs) |= 1;
		}

		if (v2 != v3) {
			BLI_edgehash_reinsert(edgehash, mf->v2, mf->v3, NULL);
			(*fs) |= 2;
		}

		if (mf->v4) {
			v4 = vertpa[mf->v4];

			if (v3 != v4) {
				BLI_edgehash_reinsert(edgehash, mf->v3, mf->v4, NULL);
				(*fs) |= 4;
			}

			if (v1 != v4) {
				BLI_edgehash_reinsert(edgehash, mf->v1, mf->v4, NULL);
				(*fs) |= 8;
			}

			/* mark center vertex as a fake edge split */
			if (*fs == 15)
				BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL);
		}
		else {
			(*fs) |= 16; /* mark face as tri */

			if (v1 != v3) {
				BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL);
				(*fs) |= 4;
			}
		}
	}

	/* count splits & create indexes for new verts */
	ehi = BLI_edgehashIterator_new(edgehash);
	totesplit = totvert;
	for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
		BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totesplit));
		totesplit++;
	}
	BLI_edgehashIterator_free(ehi);

	/* count new faces due to splitting */
	for (i = 0, fs = facesplit; i < totface; i++, fs++)
		totfsplit += add_faces[*fs];
	
	splitdm = CDDM_from_template(dm, totesplit, 0, totface + totfsplit, 0, 0);
	numlayer = CustomData_number_of_layers(&splitdm->faceData, CD_MTFACE);

	/* copy new faces & verts (is it really this painful with custom data??) */
	for (i = 0; i < totvert; i++) {
		MVert source;
		MVert *dest;
		dm->getVert(dm, i, &source);
		dest = CDDM_get_vert(splitdm, i);

		DM_copy_vert_data(dm, splitdm, i, i, 1);
		*dest = source;
	}

	/* override original facepa (original pointer is saved in caller function) */

	/* BMESH_TODO, (totfsplit * 2) over allocation is used since the quads are
	 * later interpreted as tri's, for this to work right I think we probably
	 * have to stop using tessface - campbell */

	facepa = MEM_callocN(sizeof(int) * (totface + (totfsplit * 2)), "explode_facepa");
	//memcpy(facepa, emd->facepa, totface*sizeof(int));
	emd->facepa = facepa;

	/* create new verts */
	ehi = BLI_edgehashIterator_new(edgehash);
	for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
		BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2);
		esplit = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
		mv = CDDM_get_vert(splitdm, ed_v2);
		dupve = CDDM_get_vert(splitdm, esplit);

		DM_copy_vert_data(splitdm, splitdm, ed_v2, esplit, 1);

		*dupve = *mv;

		mv = CDDM_get_vert(splitdm, ed_v1);

		mid_v3_v3v3(dupve->co, dupve->co, mv->co);
	}
	BLI_edgehashIterator_free(ehi);

	/* create new faces */
	curdupface = 0; //=totface;
	//curdupin=totesplit;
	for (i = 0, fs = facesplit; i < totface; i++, fs++) {
		mf = dm->getTessFaceData(dm, i, CD_MFACE);

		switch (*fs) {
			case 3:
			case 10:
			case 11:
			case 15:
				SET_VERTS(1, 2, 3, 4);
				break;
			case 5:
			case 6:
			case 7:
				SET_VERTS(2, 3, 4, 1);
				break;
			case 9:
			case 13:
				SET_VERTS(4, 1, 2, 3);
				break;
			case 12:
			case 14:
				SET_VERTS(3, 4, 1, 2);
				break;
			case 21:
			case 23:
				SET_VERTS(1, 2, 3, 4);
				break;
			case 19:
				SET_VERTS(2, 3, 1, 4);
				break;
			case 22:
				SET_VERTS(3, 1, 2, 4);
				break;
		}

		switch (*fs) {
			case 3:
			case 6:
			case 9:
			case 12:
				remap_faces_3_6_9_12(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
				if (numlayer)
					remap_uvs_3_6_9_12(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
				break;
			case 5:
			case 10:
				remap_faces_5_10(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
				if (numlayer)
					remap_uvs_5_10(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
				break;
			case 15:
				remap_faces_15(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
				if (numlayer)
					remap_uvs_15(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
				break;
			case 7:
			case 11:
			case 13:
			case 14:
				remap_faces_7_11_13_14(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
				if (numlayer)
					remap_uvs_7_11_13_14(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
				break;
			case 19:
			case 21:
			case 22:
				remap_faces_19_21_22(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
				if (numlayer)
					remap_uvs_19_21_22(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
				break;
			case 23:
				remap_faces_23(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
				if (numlayer)
					remap_uvs_23(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
				break;
			case 0:
			case 16:
				df1 = get_dface(dm, splitdm, curdupface, i, mf);
				facepa[curdupface] = vertpa[mf->v1];

				if (df1->v4)
					df1->flag |= ME_FACE_SEL;
				else
					df1->flag &= ~ME_FACE_SEL;
				break;
		}

		curdupface += add_faces[*fs] + 1;
	}

	for (i = 0; i < curdupface; i++) {
		mf = CDDM_get_tessface(splitdm, i);
		test_index_face(mf, &splitdm->faceData, i, ((mf->flag & ME_FACE_SEL) ? 4 : 3));
	}

	BLI_edgehash_free(edgehash, NULL);
	MEM_freeN(facesplit);
	MEM_freeN(vertpa);

	CDDM_calc_edges_tessface(splitdm);
	CDDM_tessfaces_to_faces(splitdm); /*builds ngon faces from tess (mface) faces*/

	return splitdm;
}
Example #4
0
static DerivedMesh * applyModifier(ModifierData *md, Object *ob,
						DerivedMesh *derivedData,
						int UNUSED(useRenderParams),
						int UNUSED(isFinalCalc))
{
	DerivedMesh *dm = derivedData, *result;
	ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
	ParticleSimulationData sim;
	ParticleSystem *psys= NULL;
	ParticleData *pa= NULL, *pars= NULL;
	MFace *mface, *orig_mface;
	MVert *mvert, *orig_mvert;
	int i,totvert, totpart=0, totface, maxvert, maxface, first_particle=0;
	short track=ob->trackflag%3, trackneg, axis = pimd->axis;
	float max_co=0.0, min_co=0.0, temp_co[3], cross[3];
	float *size=NULL;

	DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */

	trackneg=((ob->trackflag>2)?1:0);

	if (pimd->ob==ob) {
		pimd->ob= NULL;
		return derivedData;
	}

	if (pimd->ob) {
		psys = BLI_findlink(&pimd->ob->particlesystem,pimd->psys-1);
		if (psys==NULL || psys->totpart==0)
			return derivedData;
	}
	else return derivedData;

	if (pimd->flag & eParticleInstanceFlag_Parents)
		totpart+=psys->totpart;
	if (pimd->flag & eParticleInstanceFlag_Children) {
		if (totpart==0)
			first_particle=psys->totpart;
		totpart+=psys->totchild;
	}

	if (totpart==0)
		return derivedData;

	sim.scene = md->scene;
	sim.ob = pimd->ob;
	sim.psys = psys;
	sim.psmd = psys_get_modifier(pimd->ob, psys);

	if (pimd->flag & eParticleInstanceFlag_UseSize) {
		int p;
		float *si;
		si = size = MEM_callocN(totpart * sizeof(float), "particle size array");

		if (pimd->flag & eParticleInstanceFlag_Parents) {
			for (p=0, pa= psys->particles; p<psys->totpart; p++, pa++, si++)
				*si = pa->size;
		}

		if (pimd->flag & eParticleInstanceFlag_Children) {
			ChildParticle *cpa = psys->child;

			for (p=0; p<psys->totchild; p++, cpa++, si++) {
				*si = psys_get_child_size(psys, cpa, 0.0f, NULL);
			}
		}
	}

	pars=psys->particles;

	totvert=dm->getNumVerts(dm);
	totface=dm->getNumTessFaces(dm);

	maxvert=totvert*totpart;
	maxface=totface*totpart;

	psys->lattice=psys_get_lattice(&sim);

	if (psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) {

		float min_r[3], max_r[3];
		INIT_MINMAX(min_r, max_r);
		dm->getMinMax(dm, min_r, max_r);
		min_co=min_r[track];
		max_co=max_r[track];
	}

	result = CDDM_from_template(dm, maxvert,dm->getNumEdges(dm)*totpart,maxface, 0, 0);

	mvert=result->getVertArray(result);
	orig_mvert=dm->getVertArray(dm);

	for (i=0; i<maxvert; i++) {
		MVert *inMV;
		MVert *mv = mvert + i;
		ParticleKey state;

		inMV = orig_mvert + i%totvert;
		DM_copy_vert_data(dm, result, i%totvert, i, 1);
		*mv = *inMV;

		/*change orientation based on object trackflag*/
		copy_v3_v3(temp_co, mv->co);
		mv->co[axis]=temp_co[track];
		mv->co[(axis+1)%3]=temp_co[(track+1)%3];
		mv->co[(axis+2)%3]=temp_co[(track+2)%3];

		if ((psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) && pimd->flag & eParticleInstanceFlag_Path) {
			float ran = 0.0f;
			if (pimd->random_position != 0.0f) {
				BLI_srandom(psys->seed + (i/totvert)%totpart);
				ran = pimd->random_position * BLI_frand();
			}

			if (pimd->flag & eParticleInstanceFlag_KeepShape) {
				state.time = pimd->position * (1.0f - ran);
			}
			else {
				state.time=(mv->co[axis]-min_co)/(max_co-min_co) * pimd->position * (1.0f - ran);

				if (trackneg)
					state.time=1.0f-state.time;

				mv->co[axis] = 0.0;
			}

			psys_get_particle_on_path(&sim, first_particle + i/totvert, &state,1);

			normalize_v3(state.vel);

			/* TODO: incremental rotations somehow */
			if (state.vel[axis] < -0.9999f || state.vel[axis] > 0.9999f) {
				state.rot[0] = 1;
				state.rot[1] = state.rot[2] = state.rot[3] = 0.0f;
			}
			else {
				float temp[3] = {0.0f,0.0f,0.0f};
				temp[axis] = 1.0f;

				cross_v3_v3v3(cross, temp, state.vel);

				/* state.vel[axis] is the only component surviving from a dot product with the axis */
				axis_angle_to_quat(state.rot,cross,saacos(state.vel[axis]));
			}

		}
		else {
			state.time=-1.0;
			psys_get_particle_state(&sim, first_particle + i/totvert, &state,1);
		}

		mul_qt_v3(state.rot,mv->co);
		if (pimd->flag & eParticleInstanceFlag_UseSize)
			mul_v3_fl(mv->co, size[i/totvert]);
		add_v3_v3(mv->co, state.co);
	}

	mface=result->getTessFaceArray(result);
	orig_mface=dm->getTessFaceArray(dm);

	for (i=0; i<maxface; i++) {
		MFace *inMF;
		MFace *mf = mface + i;

		if (pimd->flag & eParticleInstanceFlag_Parents) {
			if (i/totface>=psys->totpart) {
				if (psys->part->childtype==PART_CHILD_PARTICLES) {
					pa=psys->particles+(psys->child+i/totface-psys->totpart)->parent;
				}
				else {
					pa= NULL;
				}
			}
			else {
				pa=pars+i/totface;
			}
		}
		else {
			if (psys->part->childtype==PART_CHILD_PARTICLES) {
				pa=psys->particles+(psys->child+i/totface)->parent;
			}
			else {
				pa= NULL;
			}
		}

		if (pa) {
			if (pa->alive==PARS_UNBORN && (pimd->flag&eParticleInstanceFlag_Unborn)==0) continue;
			if (pa->alive==PARS_ALIVE && (pimd->flag&eParticleInstanceFlag_Alive)==0) continue;
			if (pa->alive==PARS_DEAD && (pimd->flag&eParticleInstanceFlag_Dead)==0) continue;
		}

		inMF = orig_mface + i%totface;
		DM_copy_poly_data(dm, result, i%totface, i, 1);
		*mf = *inMF;

		mf->v1+=(i/totface)*totvert;
		mf->v2+=(i/totface)*totvert;
		mf->v3+=(i/totface)*totvert;
		if (mf->v4) {
			mf->v4+=(i/totface)*totvert;
		}
	}

	CDDM_calc_edges_tessface(result);

	if (psys->lattice) {
		end_latt_deform(psys->lattice);
		psys->lattice= NULL;
	}

	if (size)
		MEM_freeN(size);

	CDDM_tessfaces_to_faces(result); /*builds ngon faces from tess (mface) faces*/
	CDDM_calc_normals(result);

	return result;
}