[Bf-blender-cvs] [0f43ba8] master: Moved particle code for distributions into own file to make hacking easier.

Lukas Tönne noreply at git.blender.org
Tue Jan 20 09:51:56 CET 2015


Commit: 0f43ba82353a261b834e1c7b01ff8bde35453b72
Author: Lukas Tönne
Date:   Tue Oct 28 16:29:33 2014 +0100
Branches: master
https://developer.blender.org/rB0f43ba82353a261b834e1c7b01ff8bde35453b72

Moved particle code for distributions into own file to make hacking
easier.

This code is badly broken and needs to be replaced, but at least having
a workable code structure might help with quick hacks to fix the worst
cases.

===================================================================

M	source/blender/blenkernel/BKE_particle.h
M	source/blender/blenkernel/CMakeLists.txt
A	source/blender/blenkernel/intern/particle_distribute.c
M	source/blender/blenkernel/intern/particle_system.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 15d3c2f..31c0125 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -279,6 +279,9 @@ BLI_INLINE void psys_frand_vec(ParticleSystem *psys, unsigned int seed, float ve
 int count_particles(struct ParticleSystem *psys);
 int count_particles_mod(struct ParticleSystem *psys, int totgr, int cur);
 
+int psys_get_child_number(struct Scene *scene, struct ParticleSystem *psys);
+int psys_get_tot_child(struct Scene *scene, struct ParticleSystem *psys);
+
 struct ParticleSystem *psys_get_current(struct Object *ob);
 /* for rna */
 short psys_get_current_num(struct Object *ob);
@@ -404,6 +407,7 @@ void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_
                          float orco[3], float ornor[3]);
 
 /* particle_system.c */
+void distribute_particles(struct ParticleSimulationData *sim, int from);
 void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
 void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
 int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, const float fw[4], struct LinkNode *node);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 28b6aaa..d94710a 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -137,6 +137,7 @@ set(SRC
 	intern/packedFile.c
 	intern/paint.c
 	intern/particle.c
+	intern/particle_distribute.c
 	intern/particle_system.c
 	intern/pbvh.c
 	intern/pbvh_bmesh.c
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
new file mode 100644
index 0000000..6e16435
--- /dev/null
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -0,0 +1,1104 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by Janne Karhu.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Raul Fernandez Hernandez (Farsthary),
+ *                 Stephen Swhitehorn,
+ *                 Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/particle_distribute.c
+ *  \ingroup bke
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_jitter.h"
+#include "BLI_kdtree.h"
+#include "BLI_math.h"
+#include "BLI_rand.h"
+#include "BLI_sort.h"
+#include "BLI_task.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_particle_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_cdderivedmesh.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_global.h"
+#include "BKE_mesh.h"
+#include "BKE_object.h"
+#include "BKE_particle.h"
+
+static void alloc_child_particles(ParticleSystem *psys, int tot)
+{
+	if (psys->child) {
+		/* only re-allocate if we have to */
+		if (psys->part->childtype && psys->totchild == tot) {
+			memset(psys->child, 0, tot*sizeof(ChildParticle));
+			return;
+		}
+
+		MEM_freeN(psys->child);
+		psys->child=NULL;
+		psys->totchild=0;
+	}
+
+	if (psys->part->childtype) {
+		psys->totchild= tot;
+		if (psys->totchild)
+			psys->child= MEM_callocN(psys->totchild*sizeof(ChildParticle), "child_particles");
+	}
+}
+
+static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *finaldm, ParticleSystem *psys)
+{
+	ChildParticle *cpa = NULL;
+	int i, p;
+	int child_nbr= psys_get_child_number(scene, psys);
+	int totpart= psys_get_tot_child(scene, psys);
+
+	alloc_child_particles(psys, totpart);
+
+	cpa = psys->child;
+	for (i=0; i<child_nbr; i++) {
+		for (p=0; p<psys->totpart; p++,cpa++) {
+			float length=2.0;
+			cpa->parent=p;
+					
+			/* create even spherical distribution inside unit sphere */
+			while (length>=1.0f) {
+				cpa->fuv[0]=2.0f*BLI_frand()-1.0f;
+				cpa->fuv[1]=2.0f*BLI_frand()-1.0f;
+				cpa->fuv[2]=2.0f*BLI_frand()-1.0f;
+				length=len_v3(cpa->fuv);
+			}
+
+			cpa->num=-1;
+		}
+	}
+	/* dmcache must be updated for parent particles if children from faces is used */
+	psys_calc_dmcache(ob, finaldm, psys);
+}
+static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
+{
+	ParticleData *pa=NULL;
+	float min[3], max[3], delta[3], d;
+	MVert *mv, *mvert = dm->getVertDataArray(dm,0);
+	int totvert=dm->getNumVerts(dm), from=psys->part->from;
+	int i, j, k, p, res=psys->part->grid_res, size[3], axis;
+
+	/* find bounding box of dm */
+	if (totvert > 0) {
+		mv=mvert;
+		copy_v3_v3(min, mv->co);
+		copy_v3_v3(max, mv->co);
+		mv++;
+		for (i = 1; i < totvert; i++, mv++) {
+			minmax_v3v3_v3(min, max, mv->co);
+		}
+	}
+	else {
+		zero_v3(min);
+		zero_v3(max);
+	}
+
+	sub_v3_v3v3(delta, max, min);
+
+	/* determine major axis */
+	axis = axis_dominant_v3_single(delta);
+	 
+	d = delta[axis]/(float)res;
+
+	size[axis] = res;
+	size[(axis+1)%3] = (int)ceil(delta[(axis+1)%3]/d);
+	size[(axis+2)%3] = (int)ceil(delta[(axis+2)%3]/d);
+
+	/* float errors grrr.. */
+	size[(axis+1)%3] = MIN2(size[(axis+1)%3],res);
+	size[(axis+2)%3] = MIN2(size[(axis+2)%3],res);
+
+	size[0] = MAX2(size[0], 1);
+	size[1] = MAX2(size[1], 1);
+	size[2] = MAX2(size[2], 1);
+
+	/* no full offset for flat/thin objects */
+	min[0]+= d < delta[0] ? d/2.f : delta[0]/2.f;
+	min[1]+= d < delta[1] ? d/2.f : delta[1]/2.f;
+	min[2]+= d < delta[2] ? d/2.f : delta[2]/2.f;
+
+	for (i=0,p=0,pa=psys->particles; i<res; i++) {
+		for (j=0; j<res; j++) {
+			for (k=0; k<res; k++,p++,pa++) {
+				pa->fuv[0] = min[0] + (float)i*d;
+				pa->fuv[1] = min[1] + (float)j*d;
+				pa->fuv[2] = min[2] + (float)k*d;
+				pa->flag |= PARS_UNEXIST;
+				pa->hair_index = 0; /* abused in volume calculation */
+			}
+		}
+	}
+
+	/* enable particles near verts/edges/faces/inside surface */
+	if (from==PART_FROM_VERT) {
+		float vec[3];
+
+		pa=psys->particles;
+
+		min[0] -= d/2.0f;
+		min[1] -= d/2.0f;
+		min[2] -= d/2.0f;
+
+		for (i=0,mv=mvert; i<totvert; i++,mv++) {
+			sub_v3_v3v3(vec,mv->co,min);
+			vec[0]/=delta[0];
+			vec[1]/=delta[1];
+			vec[2]/=delta[2];
+			pa[((int)(vec[0] * (size[0] - 1))  * res +
+			    (int)(vec[1] * (size[1] - 1))) * res +
+			    (int)(vec[2] * (size[2] - 1))].flag &= ~PARS_UNEXIST;
+		}
+	}
+	else if (ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) {
+		float co1[3], co2[3];
+
+		MFace *mface= NULL, *mface_array;
+		float v1[3], v2[3], v3[3], v4[4], lambda;
+		int a, a1, a2, a0mul, a1mul, a2mul, totface;
+		int amax= from==PART_FROM_FACE ? 3 : 1;
+
+		totface=dm->getNumTessFaces(dm);
+		mface=mface_array=dm->getTessFaceDataArray(dm,CD_MFACE);
+		
+		for (a=0; a<amax; a++) {
+			if (a==0) { a0mul=res*res; a1mul=res; a2mul=1; }
+			else if (a==1) { a0mul=res; a1mul=1; a2mul=res*res; }
+			else { a0mul=1; a1mul=res*res; a2mul=res; }
+
+			for (a1=0; a1<size[(a+1)%3]; a1++) {
+				for (a2=0; a2<size[(a+2)%3]; a2++) {
+					mface= mface_array;
+
+					pa = psys->particles + a1*a1mul + a2*a2mul;
+					copy_v3_v3(co1, pa->fuv);
+					co1[a] -= d < delta[a] ? d/2.f : delta[a]/2.f;
+					copy_v3_v3(co2, co1);
+					co2[a] += delta[a] + 0.001f*d;
+					co1[a] -= 0.001f*d;
+					
+					/* lets intersect the faces */
+					for (i=0; i<totface; i++,mface++) {
+						copy_v3_v3(v1, mvert[mface->v1].co);
+						copy_v3_v3(v2, mvert[mface->v2].co);
+						copy_v3_v3(v3, mvert[mface->v3].co);
+
+						if (isect_axial_line_tri_v3(a, co1, co2, v2, v3, v1, &lambda)) {
+							if (from==PART_FROM_FACE)
+								(pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
+							else /* store number of intersections */
+								(pa+(int)(lambda*size[a])*a0mul)->hair_index++;
+						}
+						else if (mface->v4) {
+							copy_v3_v3(v4, mvert[mface->v4].co);
+
+							if (isect_axial_line_tri_v3(a, co1, co2, v4, v1, v3, &lambda)) {
+								if (from==PART_FROM_FACE)
+									(pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
+								else
+									(pa+(int)(lambda*size[a])*a0mul)->hair_index++;
+							}
+						}
+					}
+
+					if (from==PART_FROM_VOLUME) {
+						int in=pa->hair_index%2;
+						if (in) pa->hair_index++;
+						for (i=0; i<size[0]; i++) {
+							if (in || (pa+i*a0mul)->hair_index%2)
+								(pa+i*a0mul)->flag &= ~PARS_UNEXIST;
+							/* odd intersections == in->out / out->in */
+							/* even intersections -> in stays same */
+							in=(in + (pa+i*a0mul)->hair_index) % 2;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	if (psys->part->flag & PART_GRID_HEXAGONAL) {
+		for (i=0,p=0,pa=psys->particles; i<res; i++) {
+			for (j=0; j<res; j++) {
+				for (k=0; k<res; k++,p++,pa++) {
+					if (j%2)
+						pa->fuv[0] += d/2.f;
+
+					if (k%2) {
+						pa->fuv[0] += d/2.f;
+						pa->fuv[1] += d/2.f;
+					}
+				}
+			}
+		}
+	}
+
+	if (psys->part->flag & PART_GRID_INVERT) {
+		for (i=0; i<size[0]; i++) {
+			for (j=0; j<size[1]; j++) {
+				pa=psys->particles + res*(i*res + j);
+				for (k=0; k<size[2]; k++, pa++) {
+					pa->flag ^= PARS_UNEXIST;
+				}
+			}
+		}
+	}
+
+	if (psys->part->grid_rand > 0.f) {
+		float rfac = d * psys->part->grid_rand;
+		for (p=0,pa=psys->particles; p<psys->totpart; p++,pa++) {
+			if (pa->flag & PARS_UNEXIST)
+				continue;
+
+			pa->fuv[0] += rfac * (psys_frand(psys, p + 31) - 0.5f);
+			pa->fuv[1] += rfac * (psys_frand(psys, p + 32) - 0.5f);
+			pa->fuv[2] += rfac * (psys_frand(psys,

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list