46 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++) {
98 float min[3],
max[3], delta[3], d;
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);
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;
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);
247 if (pa2 && pa2 != pa1) {
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++) {
297 for (k = 0; k <
size[2]; k++, pa++) {
306 for (p = 0, pa = psys->
particles; p < psys->totpart; p++, 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;
357 for (
i = 0;
i < num2;
i += 2) {
372 for (
i = 0;
i < 4;
i++) {
383 float vert[4][3], co[3];
423 int mid, low = 0, high = n - 1;
429 if (
sum[low] >= value) {
433 if (
sum[high - 1] < value) {
438 mid = (low + high) / 2;
440 if ((
sum[mid] >= value) && (
sum[mid - 1] < value)) {
444 if (
sum[mid] > value) {
457#define PSYS_RND_DIST_SKIP 3
460#define ONLY_WORKING_WITH_PA_VERTS 0
485 for (
int j = 0; j < 4; j++, vert++) {
486 if (*vert == pa->
num) {
497#if ONLY_WORKING_WITH_PA_VERTS
499 KDTreeNearest_3d ptn[3];
503 ctx->
mesh, from, pa->
num, pa->
num_dmcache, pa->
fuv, pa->
foffset, co1, 0, 0, 0, orco1, 0);
505 maxw = BLI_kdtree_3d_find_nearest_n(ctx->
tree, orco1, ptn, 3);
507 for (
w = 0;
w < maxw;
w++) {
508 pa->verts[
w] = ptn->
num;
514 if (rng_skip_tot > 0) {
524 int distr = ctx->
distr;
547 if (!
isnan(offset)) {
549 ctx->
jit[2 *
int(offset)], ctx->
jit[2 *
int(offset) + 1], mface->
v4, pa->
fuv);
564 if (rng_skip_tot > 0) {
573 const float *v1, *
v2, *v3, *v4;
575 float cur_d, min_d, randu, randv;
576 int distr = ctx->
distr;
600 if (!
isnan(offset)) {
602 ctx->
jit[2 *
int(offset)], ctx->
jit[2 *
int(offset) + 1], mface->
v4, pa->
fuv);
620 reinterpret_cast<const float (*)[3]
>(positions.
data()),
621 reinterpret_cast<const float (*)[3]
>(mesh->vert_normals().data()),
637 mface =
static_cast<MFace *
>(
639 for (
i = 0;
i < tot;
i++, mface++) {
644 v1 = positions[mface->
v1];
645 v2 = positions[mface->
v2];
646 v3 = positions[mface->
v3];
656 v4 = positions[mface->
v4];
683 if (rng_skip_tot > 0) {
693 float orco1[3], co1[3], nor1[3];
695 int cfrom = ctx->
cfrom;
701 if (ctx->
index[p] < 0) {
703 cpa->
fuv[0] = cpa->
fuv[1] = cpa->
fuv[2] = cpa->
fuv[3] = 0.0f;
704 cpa->
pa[0] = cpa->
pa[1] = cpa->
pa[2] = cpa->
pa[3] = 0;
710 mf = &mfaces[ctx->
index[p]];
721 KDTreeNearest_3d ptn[10];
723 float maxd , totw = 0.0f;
739 maxw = BLI_kdtree_3d_find_nearest_n(ctx->
tree, orco1, ptn, 3);
741 maxd = ptn[maxw - 1].dist;
745 for (
w = 0;
w < maxw;
w++) {
746 parent[
w] = ptn[
w].index;
747 pweight[
w] =
float(
pow(2.0,
double(-6.0f * ptn[
w].dist / maxd)));
749 for (;
w < 10;
w++) {
754 for (
w = 0,
i = 0;
w < maxw &&
i < 4;
w++) {
755 if (parent[
w] >= 0) {
756 cpa->
pa[
i] = parent[
w];
757 cpa->
w[
i] = pweight[
w];
768 for (
w = 0;
w < 4;
w++) {
776 if (rng_skip_tot > 0) {
793 for (p = task->
begin; p < task->end; p++, pa++) {
798 for (p = task->
begin; p < task->end; p++, pa++) {
803 for (p = task->
begin; p < task->end; p++, pa++) {
819 for (p = 0; p < task->
begin; p++, cpa++) {
823 for (; p < task->
end; p++, cpa++) {
830 const int *orig_index = (
const int *)user_data;
831 int index1 = orig_index[*(
const int *)p1];
832 int index2 = orig_index[*(
const int *)p2];
834 if (index1 < index2) {
837 if (index1 == index2) {
863 if (psys->
child && totchild) {
864 for (p = 0, cpa = psys->
child; p < totchild; p++, cpa++) {
865 cpa->
fuv[0] = cpa->
fuv[1] = cpa->
fuv[2] = cpa->
fuv[3] = 0.0;
868 cpa->
pa[0] = cpa->
pa[1] = cpa->
pa[2] = cpa->
pa[3] = 0;
877 pa->fuv[0] = pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
896 KDTree_3d *
tree =
nullptr;
897 Mesh *mesh =
nullptr;
898 float *
jit =
nullptr;
901 int totelem = 0, totpart, *particle_element =
nullptr, children = 0, totseam = 0;
902 int jitlevel = 1, distr;
903 float *element_weight =
nullptr, *jitter_offset =
nullptr, *vweight =
nullptr;
904 float cur, maxweight = 0.0, tweight, totweight, inv_totweight, co[3],
nor[3], orco[3];
907 if (
ELEM(
nullptr, ob, psys, psys->
part)) {
917 if (!final_mesh->
runtime->deformed_only &&
921 "Can't create particles with the current modifier stack, disable destructive modifiers\n");
958 if (mesh != final_mesh) {
980 tree = BLI_kdtree_3d_new(totpart);
982 for (p = 0, pa = psys->
particles; p < totpart; p++, pa++) {
995 BLI_kdtree_3d_insert(
tree, p, orco);
998 BLI_kdtree_3d_balance(
tree);
1004 distr = part->
distr;
1023 const float (*orcodata)[3] =
static_cast<const float (*)[3]
>(
1027 tree = BLI_kdtree_3d_new(totvert);
1029 for (p = 0; p < totvert; p++) {
1037 BLI_kdtree_3d_insert(
tree, p, co);
1040 BLI_kdtree_3d_balance(
tree);
1051 fprintf(stderr,
"Particle distribution error: Nothing to emit from!\n");
1054 if (mesh != final_mesh) {
1058 BLI_kdtree_3d_free(
tree);
1070 float totarea = 0.0f, co1[3], co2[3], co3[3], co4[3];
1071 const float (*orcodata)[3];
1077 for (
i = 0;
i < totelem;
i++) {
1105 maxweight = std::max(cur, maxweight);
1107 element_weight[
i] = cur;
1111 for (
i = 0;
i < totelem;
i++) {
1112 element_weight[
i] /= totarea;
1115 maxweight /= totarea;
1118 float min = 1.0f /
float(std::min(totelem, totpart));
1119 for (
i = 0;
i < totelem;
i++) {
1120 element_weight[
i] =
min;
1130 for (
i = 0;
i < totelem;
i++) {
1131 element_weight[
i] *= vweight[
i];
1137 for (
i = 0;
i < totelem;
i++) {
1139 tweight = vweight[mf->
v1] + vweight[mf->
v2] + vweight[mf->
v3];
1142 tweight += vweight[mf->
v4];
1149 element_weight[
i] *= tweight;
1158 for (
i = 0;
i < totelem;
i++) {
1159 if (element_weight[
i] > 0.0f) {
1161 totweight += element_weight[
i];
1165 if (totmapped == 0) {
1167 if (mesh != final_mesh) {
1170 BLI_kdtree_3d_free(
tree);
1178 inv_totweight = 1.0f / totweight;
1190 for (
i = 0;
i < totelem && element_weight[
i] == 0.0f;
i++) {
1193 element_sum[i_mapped] = element_weight[
i] * inv_totweight;
1194 element_map[i_mapped] =
i;
1196 for (
i++;
i < totelem;
i++) {
1197 if (element_weight[
i] > 0.0f) {
1198 element_sum[i_mapped] = element_sum[i_mapped - 1] + element_weight[
i] * inv_totweight;
1200 if (element_sum[i_mapped] > element_sum[i_mapped - 1]) {
1201 element_map[i_mapped] =
i;
1206 totmapped = i_mapped;
1210 for (p = 0; p < totpart; p++) {
1215 particle_element[p] = element_map[eidx];
1218 jitter_offset[particle_element[p]] =
pos;
1224 step = (totpart < 2) ? 0.5 : 1.0 / double(totpart);
1232 pos = (totpart < totmapped) ? 0.5 /
double(totmapped) :
1235 for (
i = 0, p = 0; p < totpart; p++,
pos +=
step) {
1236 for (; (
i < totmapped - 1) && (
pos > double(element_sum[
i]));
i++) {
1240 particle_element[p] = element_map[
i];
1242 jitter_offset[particle_element[p]] =
pos;
1252 const int *orig_index =
nullptr;
1256 orig_index =
static_cast<const int *
>(
1262 orig_index =
static_cast<const int *
>(
1272 (
void *)orig_index);
1280 if (jitlevel == 0) {
1281 jitlevel = totpart / totelem;
1285 jitlevel = std::max(jitlevel, 3);
1293 if (jitlevel < 25) {
1300 jit,
sizeof(
float[2]), jitlevel, psys->
seed);
1308 ctx->
index = particle_element;
1311 ctx->
jitoff = jitter_offset;
1312 ctx->
weight = element_weight;
1365 if (ctx.
mesh != final_mesh) {
1379 fprintf(stderr,
"Shape emission not yet possible!\n");
1385 int distr_error = 0;
1388 if (psmd->mesh_final) {
1402 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)
float * psys_cache_vgroup(struct Mesh *mesh, struct ParticleSystem *psys, int vgroup)
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])
blender::Vector< ParticleTask > psys_tasks_create(struct ParticleThreadContext *ctx, int startpart, int endpart)
void psys_tasks_free(blender::Vector< ParticleTask > &tasks)
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
ATTR_WARN_UNUSED_RESULT const size_t num
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)
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)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
static T sum(const btAlignedObjectArray< T > &items)
static unsigned long seed
constexpr const T * data() const
blender::gpu::Batch * quad
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
float length(VecOp< float, D >) RET
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
ccl_device_inline float2 fmod(const float2 a, const float b)
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
ParticleThreadContext * ctx
struct ParticleData * tpars
struct ParticleSeam * seams
struct ParticleSimulationData sim