Small addition to particle grid distribution:
* New option to distribute particles in a hexagonal grid. * This is much more stable for fluids than normal grid distribution and looks quite nice otherwise too :) * Also some small scale code cleanup of grid distribution code.
This commit is contained in:
parent
c68a59175e
commit
7b4c4183f3
|
@ -197,6 +197,7 @@ class PARTICLE_PT_emission(ParticleButtonsPanel, bpy.types.Panel):
|
|||
row = layout.row()
|
||||
if part.distribution == 'GRID':
|
||||
row.prop(part, "invert_grid")
|
||||
row.prop(part, "hexagonal_grid")
|
||||
else:
|
||||
row.prop(part, "use_emit_random")
|
||||
row.prop(part, "use_even_distribution")
|
||||
|
|
|
@ -411,8 +411,8 @@ static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys)
|
|||
mv=mvert;
|
||||
|
||||
/* find bounding box of dm */
|
||||
VECCOPY(min,mv->co);
|
||||
VECCOPY(max,mv->co);
|
||||
copy_v3_v3(min, mv->co);
|
||||
copy_v3_v3(max, mv->co);
|
||||
mv++;
|
||||
|
||||
for(i=1; i<totvert; i++, mv++){
|
||||
|
@ -428,13 +428,13 @@ static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys)
|
|||
VECSUB(delta,max,min);
|
||||
|
||||
/* determine major axis */
|
||||
axis = (delta[0]>=delta[1])?0:((delta[1]>=delta[2])?1:2);
|
||||
|
||||
axis = (delta[0]>=delta[1]) ? 0 : ((delta[1]>=delta[2]) ? 1 : 2);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
@ -452,11 +452,11 @@ static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys)
|
|||
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->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 */
|
||||
pa->hair_index = 0; /* abused in volume calculation */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -467,9 +467,9 @@ static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys)
|
|||
|
||||
pa=psys->particles;
|
||||
|
||||
min[0]-=d/2.0f;
|
||||
min[1]-=d/2.0f;
|
||||
min[2]-=d/2.0f;
|
||||
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);
|
||||
|
@ -501,20 +501,20 @@ static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys)
|
|||
for(a2=0; a2<size[(a+2)%3]; a2++){
|
||||
mface= mface_array;
|
||||
|
||||
pa=psys->particles + a1*a1mul + a2*a2mul;
|
||||
VECCOPY(co1,pa->fuv);
|
||||
co1[a]-= d < delta[a] ? d/2.f : delta[a]/2.f;
|
||||
VECCOPY(co2,co1);
|
||||
co2[a]+=delta[a] + 0.001f*d;
|
||||
co1[a]-=0.001f*d;
|
||||
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++){
|
||||
VECCOPY(v1,mvert[mface->v1].co);
|
||||
VECCOPY(v2,mvert[mface->v2].co);
|
||||
VECCOPY(v3,mvert[mface->v3].co);
|
||||
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(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 */
|
||||
|
@ -522,9 +522,9 @@ static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys)
|
|||
}
|
||||
|
||||
if(mface->v4){
|
||||
VECCOPY(v4,mvert[mface->v4].co);
|
||||
copy_v3_v3(v4, mvert[mface->v4].co);
|
||||
|
||||
if(isect_axial_line_tri_v3(a,co1, co2, v4, v1, v3, &lambda)){
|
||||
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
|
||||
|
@ -549,6 +549,22 @@ static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys)
|
|||
}
|
||||
}
|
||||
|
||||
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++){
|
||||
|
|
|
@ -315,10 +315,10 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
|
|||
|
||||
//#define PART_BRANCHING (1<<20)
|
||||
//#define PART_ANIM_BRANCHING (1<<21)
|
||||
//#define PART_SYMM_BRANCHING (1<<24)
|
||||
|
||||
#define PART_HAIR_BSPLINE 1024
|
||||
|
||||
#define PART_GRID_HEXAGONAL (1<<24)
|
||||
#define PART_GRID_INVERT (1<<26)
|
||||
|
||||
#define PART_CHILD_EFFECT (1<<27)
|
||||
|
|
|
@ -1561,6 +1561,11 @@ static void rna_def_particle_settings(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Invert Grid", "Invert what is considered object and what is not");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "hexagonal_grid", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_GRID_HEXAGONAL);
|
||||
RNA_def_property_ui_text(prop, "Hexagonal Grid", "Create the grid in a hexagonal pattern");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "apply_effector_to_children", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_CHILD_EFFECT);
|
||||
RNA_def_property_ui_text(prop, "Effect Children", "Apply effectors to children");
|
||||
|
|
Loading…
Reference in New Issue