45 psys->
child =
nullptr;
63 const bool use_render_params)
74 for (i = 0; i < child_num; i++) {
75 for (p = 0; p < psys->
totpart; p++, cpa++) {
80 while (length >= 1.0f) {
98 float min[3], max[3], delta[3], d;
100 int totvert = mesh->verts_num, from = psys->
part->
from;
101 int i, j, k, p, res = psys->
part->
grid_res, size[3], axis;
106 for (i = 1; i < totvert; i++) {
120 d = delta[axis] /
float(res);
123 size[(axis + 1) % 3] =
int(
ceil(delta[(axis + 1) % 3] / d));
124 size[(axis + 2) % 3] =
int(
ceil(delta[(axis + 2) % 3] / d));
127 size[(axis + 1) % 3] = std::min(size[(axis + 1) % 3], res);
128 size[(axis + 2) % 3] = std::min(size[(axis + 2) % 3], res);
130 size[0] = std::max(size[0], 1);
131 size[1] = std::max(size[1], 1);
132 size[2] = std::max(size[2], 1);
135 min[0] += d < delta[0] ? d / 2.0f : delta[0] / 2.0f;
136 min[1] += d < delta[1] ? d / 2.0f : delta[1] / 2.0f;
137 min[2] += d < delta[2] ? d / 2.0f : delta[2] / 2.0f;
139 for (i = 0, p = 0, pa = psys->
particles; i < res; i++) {
140 for (j = 0; j < res; j++) {
141 for (k = 0; k < res; k++, p++, pa++) {
161 for (i = 0; i < totvert; i++) {
166 pa[(
int(vec[0] * (size[0] - 1)) * res +
int(vec[1] * (size[1] - 1))) * res +
167 int(vec[2] * (size[2] - 1))]
172 float co1[3], co2[3];
174 MFace *mface =
nullptr, *mface_array;
175 float v1[3],
v2[3], v3[3], v4[4], lambda;
176 int a, a1, a2, a0mul, a1mul, a2mul, totface;
179 totface = mesh->totface_legacy;
180 mface = mface_array =
static_cast<MFace *
>(
183 for (a = 0; a < amax; a++) {
200 for (a1 = 0; a1 < size[(a + 1) % 3]; a1++) {
201 for (a2 = 0; a2 < size[(a + 2) % 3]; a2++) {
204 pa = psys->
particles + a1 * a1mul + a2 * a2mul;
206 co1[a] -= d < delta[a] ? d / 2.0f : delta[a] / 2.0f;
208 co2[a] += delta[a] + 0.001f * d;
209 co1[a] -= 0.001f * d;
212 float ray_direction[3];
217 for (i = 0; i < totface; i++, mface++) {
225 co1, &isect_precalc, v1,
v2, v3, &lambda,
nullptr);
226 if (intersects_tri) {
227 pa1 = (pa +
int(lambda * size[a]) * a0mul);
234 pa2 = (pa +
int(lambda * size[a]) * a0mul);
240 pa1->
flag &= ~PARS_UNEXIST;
247 if (pa2 && pa2 != pa1) {
249 pa2->flag &= ~PARS_UNEXIST;
262 for (i = 0; i < size[0]; i++) {
263 if (in || (pa + i * a0mul)->hair_index % 2) {
268 in = (in + (pa + i * a0mul)->hair_index) % 2;
277 for (i = 0, p = 0, pa = psys->
particles; i < res; i++) {
278 for (j = 0; j < res; j++) {
279 for (k = 0; k < res; k++, p++, pa++) {
281 pa->
fuv[0] += d / 2.0f;
285 pa->
fuv[0] += d / 2.0f;
286 pa->
fuv[1] += d / 2.0f;
294 for (i = 0; i < size[0]; i++) {
295 for (j = 0; j < size[1]; j++) {
296 pa = psys->
particles + res * (i * res + j);
297 for (k = 0; k < size[2]; k++, pa++) {
331 for (
int k = 0; k < n; k++) {
334 out[2 * k + 0] =
fmod(
double(k) /
double(n) + ofs[0], 1.0);
335 out[2 * k + 1] =
fmod(t + ofs[1], 1.0);
343 float *jit2,
x, rad1, rad2, rad3;
351 rad2 =
float(1.0f /
float(num));
357 for (i = 0; i < num2; i += 2) {
369 jit2 =
static_cast<float *
>(
MEM_mallocN(12 +
sizeof(
float[2]) * num,
"initjit"));
371 for (i = 0; i < 4; i++) {
382 float vert[4][3], co[3];
422 int mid, low = 0, high = n - 1;
428 if (
sum[low] >= value) {
432 if (
sum[high - 1] < value) {
437 mid = (low + high) / 2;
439 if ((
sum[mid] >= value) && (
sum[mid - 1] < value)) {
443 if (
sum[mid] > value) {
456#define PSYS_RND_DIST_SKIP 3
459#define ONLY_WORKING_WITH_PA_VERTS 0
484 for (
int j = 0; j < 4; j++, vert++) {
485 if (*vert == pa->
num) {
496#if ONLY_WORKING_WITH_PA_VERTS
498 KDTreeNearest_3d ptn[3];
502 ctx->
mesh, from, pa->
num, pa->
num_dmcache, pa->
fuv, pa->
foffset, co1, 0, 0, 0, orco1, 0);
504 maxw = BLI_kdtree_3d_find_nearest_n(ctx->
tree, orco1, ptn, 3);
506 for (
w = 0;
w < maxw;
w++) {
507 pa->verts[
w] = ptn->
num;
513 if (rng_skip_tot > 0) {
523 int distr = ctx->
distr;
528 &mesh->fdata_legacy,
CD_MFACE, mesh->totface_legacy);
546 if (!isnan(offset)) {
548 ctx->
jit[2 *
int(offset)], ctx->
jit[2 *
int(offset) + 1], mface->
v4, pa->
fuv);
563 if (rng_skip_tot > 0) {
572 const float *v1, *
v2, *v3, *v4;
574 float cur_d, min_d, randu, randv;
575 int distr = ctx->
distr;
584 &mesh->fdata_legacy,
CD_MFACE, mesh->totface_legacy);
599 if (!isnan(offset)) {
601 ctx->
jit[2 *
int(offset)], ctx->
jit[2 *
int(offset) + 1], mface->
v4, pa->
fuv);
616 tot = mesh->totface_legacy;
619 reinterpret_cast<const float(*)[3]
>(positions.data()),
620 reinterpret_cast<const float(*)[3]
>(mesh->vert_normals().data()),
636 mface =
static_cast<MFace *
>(
638 for (i = 0; i < tot; i++, mface++) {
643 v1 = positions[mface->
v1];
644 v2 = positions[mface->
v2];
645 v3 = positions[mface->
v3];
655 v4 = positions[mface->
v4];
682 if (rng_skip_tot > 0) {
692 float orco1[3], co1[3], nor1[3];
694 int cfrom = ctx->
cfrom;
700 if (ctx->
index[p] < 0) {
702 cpa->
fuv[0] = cpa->
fuv[1] = cpa->
fuv[2] = cpa->
fuv[3] = 0.0f;
703 cpa->
pa[0] = cpa->
pa[1] = cpa->
pa[2] = cpa->
pa[3] = 0;
708 &mesh->fdata_legacy,
CD_MFACE, mesh->totface_legacy);
709 mf = &mfaces[ctx->
index[p]];
720 KDTreeNearest_3d ptn[10];
722 float maxd , totw = 0.0f;
738 maxw = BLI_kdtree_3d_find_nearest_n(ctx->
tree, orco1, ptn, 3);
740 maxd = ptn[maxw - 1].dist;
744 for (
w = 0;
w < maxw;
w++) {
745 parent[
w] = ptn[
w].index;
746 pweight[
w] =
float(
pow(2.0,
double(-6.0f * ptn[
w].dist / maxd)));
748 for (;
w < 10;
w++) {
753 for (
w = 0, i = 0;
w < maxw && i < 4;
w++) {
754 if (parent[
w] >= 0) {
755 cpa->
pa[i] = parent[
w];
756 cpa->
w[i] = pweight[
w];
767 for (
w = 0;
w < 4;
w++) {
775 if (rng_skip_tot > 0) {
792 for (p = task->begin; p < task->end; p++, pa++) {
797 for (p = task->begin; p < task->end; p++, pa++) {
802 for (p = task->begin; p < task->end; p++, pa++) {
818 for (p = 0; p < task->begin; p++, cpa++) {
822 for (; p < task->end; p++, cpa++) {
829 const int *orig_index = (
const int *)user_data;
830 int index1 = orig_index[*(
const int *)p1];
831 int index2 = orig_index[*(
const int *)p2];
833 if (index1 < index2) {
836 if (index1 == index2) {
862 if (psys->
child && totchild) {
863 for (p = 0, cpa = psys->
child; p < totchild; p++, cpa++) {
864 cpa->
fuv[0] = cpa->
fuv[1] = cpa->
fuv[2] = cpa->
fuv[3] = 0.0;
867 cpa->
pa[0] = cpa->
pa[1] = cpa->
pa[2] = cpa->
pa[3] = 0;
876 pa->fuv[0] = pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
895 KDTree_3d *
tree =
nullptr;
896 Mesh *mesh =
nullptr;
897 float *
jit =
nullptr;
900 int totelem = 0, totpart, *particle_element =
nullptr, children = 0, totseam = 0;
901 int jitlevel = 1, distr;
902 float *element_weight =
nullptr, *jitter_offset =
nullptr, *vweight =
nullptr;
903 float cur, maxweight = 0.0, tweight, totweight, inv_totweight, co[3],
nor[3], orco[3];
906 if (
ELEM(
nullptr, ob, psys, psys->
part)) {
916 if (!final_mesh->
runtime->deformed_only &&
920 "Can't create particles with the current modifier stack, disable destructive modifiers\n");
957 if (mesh != final_mesh) {
979 tree = BLI_kdtree_3d_new(totpart);
981 for (p = 0, pa = psys->
particles; p < totpart; p++, pa++) {
994 BLI_kdtree_3d_insert(
tree, p, orco);
997 BLI_kdtree_3d_balance(
tree);
1003 distr = part->distr;
1022 const float(*orcodata)[3] =
static_cast<const float(*)[3]
>(
1024 int totvert = mesh->verts_num;
1026 tree = BLI_kdtree_3d_new(totvert);
1028 for (p = 0; p < totvert; p++) {
1036 BLI_kdtree_3d_insert(
tree, p, co);
1039 BLI_kdtree_3d_balance(
tree);
1044 totelem = (from ==
PART_FROM_VERT) ? mesh->verts_num : mesh->totface_legacy;
1050 fprintf(stderr,
"Particle distribution error: Nothing to emit from!\n");
1053 if (mesh != final_mesh) {
1057 BLI_kdtree_3d_free(
tree);
1063 element_weight =
static_cast<float *
>(
1064 MEM_callocN(
sizeof(
float) * totelem,
"particle_distribution_weights"));
1065 particle_element =
static_cast<int *
>(
1066 MEM_callocN(
sizeof(
int) * totpart,
"particle_distribution_indexes"));
1067 jitter_offset =
static_cast<float *
>(
1068 MEM_callocN(
sizeof(
float) * totelem,
"particle_distribution_jitoff"));
1072 float totarea = 0.0f, co1[3], co2[3], co3[3], co4[3];
1073 const float(*orcodata)[3];
1078 &mesh->fdata_legacy,
CD_MFACE, mesh->totface_legacy);
1079 for (i = 0; i < totelem; i++) {
1080 MFace *mf = &mfaces[i];
1107 if (cur > maxweight) {
1111 element_weight[i] = cur;
1115 for (i = 0; i < totelem; i++) {
1116 element_weight[i] /= totarea;
1119 maxweight /= totarea;
1122 float min = 1.0f /
float(std::min(totelem, totpart));
1123 for (i = 0; i < totelem; i++) {
1124 element_weight[i] =
min;
1134 for (i = 0; i < totelem; i++) {
1135 element_weight[i] *= vweight[i];
1140 &mesh->fdata_legacy,
CD_MFACE, mesh->totface_legacy);
1141 for (i = 0; i < totelem; i++) {
1142 MFace *mf = &mfaces[i];
1143 tweight = vweight[mf->
v1] + vweight[mf->
v2] + vweight[mf->
v3];
1146 tweight += vweight[mf->
v4];
1153 element_weight[i] *= tweight;
1162 for (i = 0; i < totelem; i++) {
1163 if (element_weight[i] > 0.0f) {
1165 totweight += element_weight[i];
1169 if (totmapped == 0) {
1171 if (mesh != final_mesh) {
1174 BLI_kdtree_3d_free(
tree);
1182 inv_totweight = 1.0f / totweight;
1190 float *element_sum =
static_cast<float *
>(
1191 MEM_mallocN(
sizeof(*element_sum) * totmapped, __func__));
1192 int *element_map =
static_cast<int *
>(
MEM_mallocN(
sizeof(*element_map) * totmapped, __func__));
1195 for (i = 0; i < totelem && element_weight[i] == 0.0f; i++) {
1198 element_sum[i_mapped] = element_weight[i] * inv_totweight;
1199 element_map[i_mapped] = i;
1201 for (i++; i < totelem; i++) {
1202 if (element_weight[i] > 0.0f) {
1203 element_sum[i_mapped] = element_sum[i_mapped - 1] + element_weight[i] * inv_totweight;
1205 if (element_sum[i_mapped] > element_sum[i_mapped - 1]) {
1206 element_map[i_mapped] = i;
1211 totmapped = i_mapped;
1215 for (p = 0; p < totpart; p++) {
1220 particle_element[p] = element_map[eidx];
1223 jitter_offset[particle_element[p]] =
pos;
1229 step = (totpart < 2) ? 0.5 : 1.0 /
double(totpart);
1237 pos = (totpart < totmapped) ? 0.5 /
double(totmapped) :
1240 for (i = 0, p = 0; p < totpart; p++,
pos += step) {
1241 for (; (i < totmapped - 1) && (
pos >
double(element_sum[i])); i++) {
1245 particle_element[p] = element_map[i];
1247 jitter_offset[particle_element[p]] =
pos;
1257 const int *orig_index =
nullptr;
1260 if (mesh->verts_num) {
1261 orig_index =
static_cast<const int *
>(
1266 if (mesh->totface_legacy) {
1267 orig_index =
static_cast<const int *
>(
1277 (
void *)orig_index);
1283 jitlevel = part->userjit;
1285 if (jitlevel == 0) {
1286 jitlevel = totpart / totelem;
1295 jit =
static_cast<float *
>(
MEM_callocN((2 + jitlevel * 2) *
sizeof(
float),
"jit"));
1300 if (jitlevel < 25) {
1307 jit,
sizeof(
float[2]), jitlevel, psys->
seed);
1315 ctx->
index = particle_element;
1318 ctx->
jitoff = jitter_offset;
1319 ctx->
weight = element_weight;
1349 int i, totpart, numtasks;
1360 for (i = 0; i < numtasks; i++) {
1377 if (ctx.
mesh != final_mesh) {
1391 fprintf(stderr,
"Shape emission not yet possible!\n");
1397 int distr_error = 0;
1400 if (psmd->mesh_final) {
1414 fprintf(stderr,
"Particle distribution error!\n");
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
void BKE_id_free(Main *bmain, void *idv)
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
void BKE_mesh_orco_verts_transform(Mesh *mesh, blender::MutableSpan< blender::float3 > orco, bool invert)
void BKE_mesh_orco_ensure(Object *ob, Mesh *mesh)
void BKE_mesh_texspace_ensure(Mesh *mesh)
void BKE_mesh_tessface_ensure(Mesh *mesh)
int psys_get_child_number(struct Scene *scene, struct ParticleSystem *psys, bool use_render_params)
void psys_thread_context_init(struct ParticleThreadContext *ctx, struct ParticleSimulationData *sim)
void psys_calc_dmcache(struct Object *ob, struct Mesh *mesh_final, struct Mesh *mesh_original, struct ParticleSystem *psys)
void psys_tasks_free(struct ParticleTask *tasks, int numtasks)
float * psys_cache_vgroup(struct Mesh *mesh, struct ParticleSystem *psys, int vgroup)
void psys_tasks_create(struct ParticleThreadContext *ctx, int startpart, int endpart, struct ParticleTask **r_tasks, int *r_numtasks)
void psys_thread_context_free(struct ParticleThreadContext *ctx)
int psys_get_tot_child(struct Scene *scene, struct ParticleSystem *psys, bool use_render_params)
void psys_particle_on_dm(struct Mesh *mesh_final, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3])
void psys_interpolate_face(struct Mesh *mesh, const float(*vert_positions)[3], const float(*vert_normals)[3], const struct MFace *mface, struct MTFace *tface, const float(*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3])
BLI_INLINE float psys_frand(ParticleSystem *psys, unsigned int seed)
void BLI_jitterate1(float(*jit1)[2], float(*jit2)[2], int num, float radius1)
void BLI_jitterate2(float(*jit1)[2], float(*jit2)[2], int num, float radius2)
A KD-tree for nearest neighbor search.
void isect_ray_tri_watertight_v3_precalc(struct IsectRayPrecalc *isect_precalc, const float ray_direction[3])
bool isect_ray_tri_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2])
MINLINE int axis_dominant_v3_single(const float vec[3])
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
bool isect_ray_tri_watertight_v3(const float ray_origin[3], const struct IsectRayPrecalc *isect_precalc, const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2])
float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
void interp_weights_poly_v3(float w[], float v[][3], int n, const float co[3])
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3(float r[3])
MINLINE void zero_v4(float r[4])
MINLINE void zero_v3(float r[3])
MINLINE float normalize_v3(float n[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
struct RNG * BLI_rng_new(unsigned int seed)
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
void BLI_hammersley_1d(unsigned int n, double *r)
struct RNG * BLI_rng_new_srandom(unsigned int seed)
double BLI_rng_get_double(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void void BLI_rng_skip(struct RNG *rng, int n) ATTR_NONNULL(1)
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_array_randomize(void *data, unsigned int elem_size, unsigned int elem_num, unsigned int seed)
void BLI_qsort_r(void *a, size_t n, size_t es, BLI_sort_cmp_t cmp, void *thunk)
void BLI_task_pool_work_and_wait(TaskPool *pool)
TaskPool * BLI_task_pool_create(void *userdata, eTaskPriority priority)
void BLI_task_pool_free(TaskPool *pool)
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
#define INIT_MINMAX(min, max)
typedef double(DMatrix)[4][4]
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
__forceinline BoundBox intersect(const BoundBox &a, const BoundBox &b)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
static T sum(const btAlignedObjectArray< T > &items)
static unsigned long seed
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
blender::gpu::Batch * quad
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ccl_device_inline float2 fmod(const float2 a, const float b)
ccl_device_inline float2 floor(const float2 a)
ccl_device_inline float3 ceil(const float3 a)
Frequency::GEOMETRY nor[]
static void init_mv_jit(float *jit, int num, int seed2, float amount)
static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, int p)
static void distribute_particles_on_shape(ParticleSimulationData *sim, int)
#define PSYS_RND_DIST_SKIP
static void exec_distribute_child(TaskPool *__restrict, void *taskdata)
static void psys_task_init_distribute(ParticleTask *task, ParticleSimulationData *sim)
static void distribute_simple_children(Scene *scene, Object *ob, Mesh *final_mesh, Mesh *deform_mesh, ParticleSystem *psys, const bool use_render_params)
static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, int p)
static void distribute_invalid(ParticleSimulationData *sim, int from)
static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, int p)
static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, int p)
static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
void distribute_particles(ParticleSimulationData *sim, int from)
static int distribute_binary_search(const float *sum, int n, float value)
static void exec_distribute_parent(TaskPool *__restrict, void *taskdata)
static void psys_uv_to_w(float u, float v, int quad, float *w)
static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, ParticleSimulationData *sim, int from)
static void hammersley_create(float *out, int n, int seed, float amount)
static void alloc_child_particles(ParticleSystem *psys, int tot)
static int distribute_compare_orig_index(const void *p1, const void *p2, void *user_data)
MeshRuntimeHandle * runtime
struct Depsgraph * depsgraph
struct ParticleSystemModifierData * psmd
struct ParticleSystem * psys
struct Mesh * mesh_original
struct ParticleData * tpars
struct ParticleSeam * seams
struct ParticleSimulationData sim