94 if (edit ==
nullptr) {
115 if (edit ==
nullptr || edit->
psys ==
nullptr) {
138 if (edit ==
nullptr) {
184 float co[3], mat[4][4];
191 if ((psys = edit->
psys)) {
275 for (
int p = 0; p < edit->
totpoint; p++) {
278 for (
int k = 0; k <
point->totkey; k++) {
280 key->
co = hair_key->
co;
304 if (pset ==
nullptr || ob ==
nullptr) {
342 if (create && !psys->
edit) {
537 data->shape_bvh = {};
562 if (
data->rng !=
nullptr) {
574 data->depths =
nullptr;
608 if (screen_co[0] >= 0 && screen_co[0] < vd->
w && screen_co[1] >= 0 && screen_co[1] < vd->
h) {
611 depth = vd->
depths[screen_co[1] * vd->
w + screen_co[0]];
620 if (win[2] - 0.00001f > depth) {
638 dx =
data->mval[0] - screen_co[0];
639 dy =
data->mval[1] - screen_co[1];
640 dist =
sqrtf(dx * dx + dy * dy);
667 if (screen_co[0] >
data->rect->xmin && screen_co[0] <
data->rect->xmax &&
668 screen_co[1] >
data->rect->ymin && screen_co[1] <
data->rect->ymax)
711 const float mat[4][4],
712 const float imat[4][4],
722 float mouse_distance);
735 int nearest_point, nearest_key;
736 float dist =
data->rad;
755 nearest_key =
point->totkey - 1;
787 if (nearest_point != -1) {
788 func(
data, nearest_point, nearest_key,
true);
811 if (selected == 0 || key->flag &
PEK_SELECT) {
812 float mouse_distance;
814 func(
data, p, mouse_distance);
822 if (selected == 0 || key->flag &
PEK_SELECT) {
823 float mouse_distance;
825 func(
data, p, mouse_distance);
855 const int selected = iter_data->
selected;
856 float mat[4][4], imat[4][4];
865 float mouse_distance;
872 iter_data->
func(
data, mat, imat, iter,
point->totkey - 1, key, mouse_distance);
883 float mouse_distance;
890 iter_data->
func(
data, mat, imat, iter, k, key, mouse_distance);
908 iter_data.
edit = edit;
910 iter_data.
func = func;
935 func(
data, p, k,
true);
987 KDTreeNearest_3d nearest;
990 float mat[4][4], co[3];
1001 tree = BLI_kdtree_3d_new(totpart);
1010 BLI_kdtree_3d_insert(
tree, p, co);
1013 BLI_kdtree_3d_balance(
tree);
1028 index = BLI_kdtree_3d_find_nearest(
tree, co, &nearest);
1031 if (index != -1 && index != p && (nearest.dist <= 0.0002f)) {
1050 BLI_kdtree_3d_free(
tree);
1060 float mat[4][4], mmat[4][4], immat[4][4];
1087 mpoint = edit->
points + mi;
1104 mkey = mpoint->
keys;
1105 for (k = 0; k < mpa->
totkey; k++, mkey++, mhkey++) {
1106 mkey->co = mhkey->
co;
1107 mkey->time = &mhkey->
time;
1120 mkey = mpoint->
keys;
1121 for (k = 0; k < pa->
totkey; k++, hkey++, mhkey++, key++, mkey++) {
1124 mhkey->
co[0] = -mhkey->
co[0];
1155 if (psmd_eval ==
nullptr || psmd_eval->
mesh_final ==
nullptr) {
1217 float hairimat[4][4], hairmat[4][4];
1219 float *vec, *
nor, dvec[3],
dot, dist_1st = 0.0f;
1220 const float dist = iter_data->
dist;
1232 dist_1st *= dist * emitterdist;
1235 index = BLI_kdtree_3d_find_nearest(edit->
emitter_field, key->
co,
nullptr);
1246 if (
dot < dist_1st) {
1258 dist_1st *= 1.3333f;
1291 iter_data.
psys = psys;
1292 iter_data.
edit = edit;
1293 iter_data.
dist = dist;
1342 iter_data.
edit = edit;
1366 float dv0[3] = {0.0f, 0.0f, 0.0f};
1367 float dv1[3] = {0.0f, 0.0f, 0.0f};
1368 float dv2[3] = {0.0f, 0.0f, 0.0f};
1369 for (
int j = 1; j <
point->totkey; j++) {
1374 key =
point->keys + 1;
1376 dv1[0] = dv1[1] = dv1[2] = 0.0;
1381 dv0[0] = dv0[1] = dv0[2] = 0.0;
1384 for (; k <
point->totkey; k++, key++) {
1390 if (k < point->totkey - 1) {
1415 iter_data.
edit = edit;
1416 iter_data.
pset = pset;
1428 if (edit ==
nullptr) {
1434 for (k = 0; k <
point->totkey - 1; k++, key++) {
1435 key->length =
len_v3v3(key->co, (key + 1)->co);
1461 MEM_callocN(
sizeof(
float[6]) * totface,
"emitter cosnos"));
1471 for (i = 0; i < totface; i++, vec += 6,
nor += 6) {
1472 const MFace *mface = &mfaces[i];
1543 float hairmat[4][4];
1545 if (psys ==
nullptr || psys->
edit ==
nullptr || psmd_eval ==
nullptr ||
1568 float vec1[3], vec2[3], frs_sec, dfra;
1582 dfra = *(key + 1)->time - *key->time;
1590 if (
point->totkey > 2) {
1597 else if (k ==
point->totkey - 1) {
1598 dfra = *key->time - *(key - 1)->time;
1606 if (
point->totkey > 2) {
1614 dfra = *(key + 1)->time - *(key - 1)->time;
1620 sub_v3_v3v3(key->vel, (key + 1)->co, (key - 1)->co);
1702 data->is_changed =
true;
1712 if (sel_op_result != -1) {
1715 data->is_changed =
true;
1745 bool changed =
false;
1801 bool changed =
false;
1818 ot->name =
"(De)select All";
1819 ot->idname =
"PARTICLE_OT_select_all";
1820 ot->description =
"(De)select all particles' keys";
1851 user_data->
key = key;
1852 data->is_changed =
true;
1867 data.user_data = &user_data;
1869 bool found =
data.is_changed;
1872 *r_point = user_data.
point;
1873 *r_key = user_data.
key;
1892 bool changed =
false;
1899 else if (found ||
params->deselect_all) {
1906 switch (
params->sel_op) {
1949 return changed || found;
1988 action =
data.select_toggle_action;
1991 data.select_action = action;
1994 if (
data.is_changed) {
2004 ot->name =
"Select Roots";
2005 ot->idname =
"PARTICLE_OT_select_roots";
2006 ot->description =
"Select roots of all visible particles";
2030 if (
point->totkey == 0) {
2061 action =
data.select_toggle_action;
2064 data.select_action = action;
2067 if (
data.is_changed) {
2079 ot->name =
"Select Tips";
2080 ot->idname =
"PARTICLE_OT_select_tips";
2081 ot->description =
"Select tips of all visible particles";
2105 {0,
nullptr, 0,
nullptr,
nullptr},
2154 if (
data.is_changed) {
2164 ot->name =
"Select Random";
2165 ot->idname =
"PARTICLE_OT_select_random";
2166 ot->description =
"Select a randomly distributed set of hair or points";
2182 "Select either hair or points");
2208 ot->name =
"Select Linked All";
2209 ot->idname =
"PARTICLE_OT_select_linked";
2210 ot->description =
"Select all keys linked to already selected ones";
2229 mval[0] = location[0];
2230 mval[1] = location[1];
2254 ot->name =
"Select Linked";
2255 ot->idname =
"PARTICLE_OT_select_linked_pick";
2256 ot->description =
"Select nearest particle from mouse pointer";
2268 ot->srna,
"deselect",
false,
"Deselect",
"Deselect linked keys rather than selecting them");
2280 bool changed =
false;
2335 bool is_changed =
data.is_changed;
2379 if (wm_userdata->
data ==
nullptr) {
2393 if (
data->is_changed) {
2397 return data->is_changed;
2416 float co[3], mat[4][4];
2446 const bool is_select = key->flag &
PEK_SELECT;
2451 {
reinterpret_cast<const blender::int2 *
>(mcoords), mcoords_len},
2458 if (sel_op_result != -1) {
2461 data.is_changed =
true;
2466 if (
point->totkey) {
2470 const bool is_select = key->flag &
PEK_SELECT;
2475 {
reinterpret_cast<const blender::int2 *
>(mcoords), mcoords_len},
2482 if (sel_op_result != -1) {
2485 data.is_changed =
true;
2491 bool is_changed =
data.is_changed;
2548 ot->name =
"Hide Selected";
2549 ot->idname =
"PARTICLE_OT_hide";
2550 ot->description =
"Hide selected particles";
2561 ot->srna,
"unselected",
false,
"Unselected",
"Hide unselected rather than selected");
2600 ot->name =
"Reveal";
2601 ot->idname =
"PARTICLE_OT_reveal";
2602 ot->description =
"Show hidden particles";
2633 else if (k ==
point->totkey - 1) {
2649 data->is_changed =
true;
2670 ot->name =
"Select Less";
2671 ot->idname =
"PARTICLE_OT_select_less";
2672 ot->description =
"Deselect boundary selected keys of each particle";
2704 else if (k ==
point->totkey - 1) {
2721 data->is_changed =
true;
2742 ot->name =
"Select More";
2743 ot->idname =
"PARTICLE_OT_select_more";
2744 ot->description =
"Select keys linked to boundary selected keys of each particle";
2768 HairKey *key, *new_keys, *okey;
2770 float dval, sta, end;
2780 key = new_keys =
static_cast<HairKey *
>(
2789 end = (key +
data->totrekey - 1)->time = (okey + pa->
totkey - 1)->time;
2790 dval = (end - sta) /
float(
data->totrekey - 1);
2793 for (k = 1, key++; k <
data->totrekey - 1; k++, key++) {
2797 key->
time = sta + k * dval;
2804 pa->
hair = new_keys;
2814 for (k = 0, key = pa->
hair; k < pa->totkey; k++, key++, ekey++) {
2849 ot->idname =
"PARTICLE_OT_rekey";
2850 ot->description =
"Change the number of keys of selected particles (root and tip keys included)";
2861 RNA_def_int(
ot->srna,
"keys_number", 2, 2, INT_MAX,
"Number of Keys",
"", 2, 100);
2877 if (!edit || !edit->
psys) {
2895 for (k = 1, key++; k < pa->
totkey; k++, key++) {
2905 pa->
hair = new_keys;
2908 for (k = 0, key = pa->
hair, ekey = edit->
points[pa_index].
keys; k < pa->totkey;
2931 int i, new_totpart = psys->
totpart, removed = 0;
2947 if (new_totpart != psys->
totpart) {
2954 if (
ELEM(
nullptr, new_pars, new_points)) {
2993 edit->
points = new_points;
2999 psys->
child =
nullptr;
3013 HairKey *hkey, *nhkey, *new_hkeys =
nullptr;
3034 new_totkey =
point->totkey;
3039 if (new_totkey < 2) {
3053 if (new_totkey != pa->
totkey) {
3054 nhkey = new_hkeys =
static_cast<HairKey *
>(
3061 while (key->flag &
PEK_TAG && hkey < pa->hair + pa->
totkey) {
3066 if (hkey < pa->hair + pa->
totkey) {
3072 nkey->
co = nhkey->
co;
3075 nkey->
flag = key->flag;
3076 nkey->
ftime = key->ftime;
3077 nkey->
length = key->length;
3093 pa->
hair = new_hkeys;
3094 point->keys = new_keys;
3119 HairKey *key, *nkey, *new_keys;
3123 short totnewkey = 0;
3131 for (k = 0, ekey =
point->keys; k < pa->totkey - 1; k++, ekey++) {
3137 if (totnewkey == 0) {
3143 nkey = new_keys =
static_cast<HairKey *
>(
3151 for (k = 0, ekey =
point->keys; k < pa->totkey - 1; k++, key++, ekey++) {
3153 memcpy(nkey, key,
sizeof(
HairKey));
3156 nekey->
co = nkey->
co;
3163 nkey->
time = (key->
time + (key + 1)->time) * 0.5f;
3164 state.time = (endtime != 0.0f) ? nkey->
time / endtime : 0.0f;
3168 nekey->
co = nkey->
co;
3180 memcpy(nkey, key,
sizeof(
HairKey));
3183 nekey->
co = nkey->
co;
3189 pa->
hair = new_keys;
3194 point->keys = new_ekeys;
3220 ot->name =
"Subdivide";
3221 ot->idname =
"PARTICLE_OT_subdivide";
3222 ot->description =
"Subdivide selected particles segments (adds keys)";
3247 KDTreeNearest_3d nearest[10];
3250 int n, totn, removed, totremoved;
3271 BLI_kdtree_3d_insert(
tree, p, co);
3274 BLI_kdtree_3d_balance(
tree);
3283 totn = BLI_kdtree_3d_find_nearest_n(
tree, co, nearest, 10);
3285 for (n = 0; n < totn; n++) {
3287 if (nearest[n].index > p && nearest[n].dist < threshold) {
3296 BLI_kdtree_3d_free(
tree);
3300 totremoved += removed;
3303 if (totremoved == 0) {
3318 ot->name =
"Remove Doubles";
3319 ot->idname =
"PARTICLE_OT_remove_doubles";
3320 ot->description =
"Remove selected particles close enough of others";
3336 "Threshold distance within which particles are removed",
3363 hkey = pa->
hair + k;
3377 ot->name =
"Weight Set";
3378 ot->idname =
"PARTICLE_OT_weight_set";
3379 ot->description =
"Set the weight of selected keys";
3394 "Interpolation factor between current brush weight, and keys' weights",
3459 {
DEL_KEY,
"KEY", 0,
"Key",
""},
3460 {0,
nullptr, 0,
nullptr,
nullptr},
3505 ot->name =
"Delete";
3506 ot->idname =
"PARTICLE_OT_delete";
3507 ot->description =
"Delete selected particles or keys";
3523 "Delete a full particle or only keys");
3543 int *mirrorfaces =
nullptr;
3544 int rotation, totpart, newtotpart;
3564 ob,
nullptr, use_dm_final_indices ? psmd_eval->
mesh_final :
nullptr);
3591 if (newtotpart != psys->
totpart) {
3592 const MFace *mtessface = use_dm_final_indices ?
3614 edit->
points = new_points;
3622 newpoint = edit->
points + totpart;
3626 const int pa_num = pa->
num;
3632 if (!(
point->flag &
PEP_TAG) || mirrorfaces[pa_num * 2] == -1) {
3647 rotation = mirrorfaces[pa_num * 2 + 1];
3648 newpa->
fuv[0] = pa->
fuv[2];
3649 newpa->
fuv[1] = pa->
fuv[1];
3650 newpa->
fuv[2] = pa->
fuv[0];
3651 newpa->
fuv[3] = pa->
fuv[3];
3652 while (rotation--) {
3653 if (mtessface[pa_num].v4) {
3664 newpa->
num = mirrorfaces[pa_num * 2];
3666 if (use_dm_final_indices) {
3675 key = newpoint->
keys;
3676 for (k = 0, hkey = newpa->
hair; k < newpa->totkey; k++, hkey++, key++) {
3678 key->time = &hkey->
time;
3733 ot->name =
"Mirror";
3734 ot->idname =
"PARTICLE_OT_mirror";
3735 ot->description =
"Duplicate and mirror the selected particles along the local X axis";
3757 float mouse_distance)
3766 fac =
float(
pow(
double(1.0f - mouse_distance /
data->rad),
double(
data->combfac)));
3783 float rad2, cut_time = 1.0;
3784 float x0, x1, v0, v1, o0, o1, xo0, xo1, d, dv;
3809 x0 =
float(screen_co[0]);
3810 x1 =
float(screen_co[1]);
3825 for (k = 1, key++; k <= keys; k++, key++) {
3831 x0 =
float(screen_co[0]);
3832 x1 =
float(screen_co[1]);
3839 v0 =
float(screen_co[0]) - x0;
3840 v1 =
float(screen_co[1]) - x1;
3842 dv = v0 * v0 + v1 * v1;
3844 d = (v0 * xo1 - v1 * xo0);
3846 d = dv * rad2 - d * d;
3851 cut_time = -(v0 * xo0 + v1 * xo1 + d);
3853 if (cut_time > 0.0f) {
3856 if (cut_time < 1.0f) {
3857 cut_time +=
float(k - 1);
3858 cut_time /=
float(keys);
3865 x0 =
float(screen_co[0]);
3866 x1 =
float(screen_co[1]);
3874 if (cut_time < 0.0f) {
3889 float dvec[3], pvec[3] = {0.0f, 0.0f, 0.0f};
3912 float mat[4][4], imat[4][4];
3916 float co_root[3], no_root[3];
3917 float co_prev[3], co[3];
3918 float fac = 0.0f, length_accum = 0.0f;
3919 bool puff_volume =
false;
3920 bool changed =
false;
3952 point_index = BLI_kdtree_3d_find_nearest(edit->
emitter_field, kco,
nullptr);
3953 if (point_index == -1) {
3968 fac =
float(
pow(
double(1.0f - mouse_distance /
data->rad),
double(
data->pufffac)));
4034 float oco[3], onor[3];
4042 point_index = BLI_kdtree_3d_find_nearest(edit->
emitter_field, kco,
nullptr);
4043 if (point_index != -1) {
4120 float vec[3], dvec[3];
4139 const float v1[3],
const float v2[3],
const float v3[3],
const float v4[3],
float w[4])
4141 float co[3], vert[4][3];
4148 co[0] = v1[0] *
w[0] +
v2[0] *
w[1] + v3[0] *
w[2] + v4[0] *
w[3];
4149 co[1] = v1[1] *
w[0] +
v2[1] *
w[1] + v3[1] *
w[2] + v4[1] *
w[3];
4150 co[2] = v1[2] *
w[0] +
v2[2] *
w[1] + v3[2] *
w[2] + v4[2] *
w[3];
4171 const MFace *mface =
nullptr;
4176 float cur_ipoint[3];
4178 if (mesh ==
nullptr) {
4183 if (mesh ==
nullptr) {
4189 if (mesh ==
nullptr) {
4197 if (pa_minmax ==
nullptr) {
4212 for (i = 0; i < totface; i++, mface++) {
4230 if (face_minmax ==
nullptr) {
4250 if (radius > 0.0f) {
4252 if (cur_d < *min_d) {
4261 if (cur_d < *min_d) {
4272 if (cur_d < *min_d) {
4274 min_w[0] = 1.0f - cur_uv[0] - cur_uv[1];
4275 min_w[1] = cur_uv[0];
4276 min_w[2] = cur_uv[1];
4287 if (cur_d < *min_d) {
4289 min_w[0] = 1.0f - cur_uv[0] - cur_uv[1];
4291 min_w[2] = cur_uv[0];
4292 min_w[3] = cur_uv[1];
4333 const int number = iter_data->
number;
4334 const short size = iter_data->
size;
4340 if (tls->
rng ==
nullptr) {
4345 while (dmx * dmx + dmy * dmy > size2) {
4356 mco[0] =
data->mval[0] + dmx;
4357 mco[1] =
data->mval[1] + dmy;
4359 float co1[3], co2[3];
4407 void *__restrict join_v,
4408 void *__restrict chunk_v)
4416 void *__restrict chunk_v)
4419 if (tls->
rng !=
nullptr) {
4436 int i, k, n = 0, totpart = psys->
totpart;
4437 float co1[3], imat[4][4];
4438 float framestep, timestep;
4457 sim.
psmd = psmd_eval;
4476 iter_data.
scene = scene;
4478 iter_data.
mesh = mesh;
4480 iter_data.
number = number;
4499 for (
int current_iter = 0, new_index = 0; current_iter < number; current_iter++) {
4503 if (new_index != current_iter) {
4507 memcpy(add_pars + new_index, add_pars + current_iter,
sizeof(
ParticleData));
4513 int newtotpart = totpart + n;
4514 float hairmat[4][4], cur_co[3];
4515 KDTree_3d *
tree =
nullptr;
4537 edit->
points = new_points;
4545 for (i = 0, pa = psys->
particles; i < totpart; i++, pa++) {
4557 BLI_kdtree_3d_insert(
tree, i, cur_co);
4560 BLI_kdtree_3d_balance(
tree);
4569 for (i = totpart; i < newtotpart; i++, pa++,
point++) {
4570 memcpy(pa, add_pars + i - totpart,
sizeof(
ParticleData));
4577 for (k = 0, hkey = pa->
hair; k < pa->totkey; k++, hkey++, key++) {
4600 KDTreeNearest_3d ptn[3];
4602 float maxd, totw = 0.0, weight[3];
4615 maxw = BLI_kdtree_3d_find_nearest_n(
tree, co1, ptn, 3);
4617 maxd = ptn[maxw - 1].dist;
4619 for (
w = 0;
w < maxw;
w++) {
4620 weight[
w] =
float(
pow(2.0,
double(-6.0f * ptn[
w].dist / maxd)));
4623 for (;
w < 3;
w++) {
4628 for (
w = 0;
w < maxw;
w++) {
4633 for (
w = 0;
w < maxw;
w++) {
4634 weight[
w] = 1.0f / maxw;
4642 thkey->
time = pa->
time + k * framestep;
4644 key3[0].
time = thkey->
time / 100.0f;
4675 for (k = 0, hkey = pa->
hair; k < pset->totaddkey; k++, hkey++) {
4677 hkey->
time += k * framestep;
4681 for (k = 0, hkey = pa->
hair; k < pset->totaddkey; k++, hkey++) {
4689 BLI_kdtree_3d_free(
tree);
4740 bedit->
scene = scene;
4765 float vec[3], mousef[2];
4767 int flip, mouse[2], removed = 0, added = 0, selected = 0, tot_steps = 1, step = 1;
4776 mouse[0] = mousef[0];
4777 mouse[1] = mousef[1];
4798 (dx != 0 || dy != 0)) ||
4810 dx /=
float(tot_steps);
4811 dy /=
float(tot_steps);
4813 for (step = 1; step <= tot_steps; step++) {
4814 mval[0] = bedit->
lastmouse[0] + step * dx;
4815 mval[1] = bedit->
lastmouse[1] + step * dy;
4819 const float xy_delta[2] = {dx, dy};
4824 if (
data.combfac < 0.0f) {
4825 data.combfac = 1.0f - 9.0f *
data.combfac;
4828 data.combfac = 1.0f -
data.combfac;
4869 if (brush->
invert ^ flip) {
4870 data.growfac = 1.0f -
data.growfac;
4873 data.growfac = 1.0f +
data.growfac;
4888 data.select = selected;
4891 if (
data.pufffac < 0.0f) {
4892 data.pufffac = 1.0f - 9.0f *
data.pufffac;
4895 data.pufffac = 1.0f -
data.pufffac;
4987 pset->
flag |= lock_root;
5046 switch (event->
type) {
5076 ot->name =
"Brush Edit";
5077 ot->idname =
"PARTICLE_OT_brush_edit";
5078 ot->description =
"Apply a stroke of brush to the particles";
5128 data->bvhdata.raycast_callback(&
data->bvhdata, index, ray, hit);
5130 if (hit->
index != -1) {
5139 const float dir[3] = {1.0f, 0.0f, 0.0f};
5152 return (userdata.
num_hits % 2) == 1;
5163 float cut_time = 1.0;
5180 for (k = 0; k < totkeys; k++, key++) {
5183 float co_curr_shape[3], co_next_shape[3];
5190 sub_v3_v3v3(dir_shape, co_next_shape, co_curr_shape);
5193 memset(&hit, 0,
sizeof(hit));
5195 hit.
dist = len_shape;
5201 data->shape_bvh.raycast_callback,
5203 if (hit.
index >= 0) {
5204 if (hit.
dist < len_shape) {
5205 cut_time = ((hit.
dist / len_shape) +
float(k)) /
float(totkeys);
5214 if (cut_time < 0.0f) {
5286 pset->
flag |= lock_root;
5294 ot->name =
"Shape Cut";
5295 ot->idname =
"PARTICLE_OT_shape_cut";
5296 ot->description =
"Cut hair to conform to the set shape object";
5325 if (psmd !=
nullptr) {
5331 if (!(psys && psmd && psmd_eval->
mesh_final) && !cache) {
5343 edit = (psys) ? psys->
edit : cache->
edit;
5359 if (psys && !cache) {
5381 key->time = &hkey->
time;
5399 edit->
psys =
nullptr;
5412 if (!
point->totkey) {
5424 key->ftime =
float(pm->frame);
5425 key->time = &key->ftime;
5435 if (psys && !cache) {
5463 if (psys->edit !=
nullptr) {
5465 psys->free_edit(psys->edit);
5466 psys->free_edit =
nullptr;
5467 psys->edit =
nullptr;
5492 if (edit && edit->
psys) {
5538 const bool is_mode_set = (ob->
mode & mode_flag) != 0;
5564 ot->name =
"Particle Edit Toggle";
5565 ot->idname =
"PARTICLE_OT_particle_edit_toggle";
5566 ot->description =
"Toggle particle edit mode";
5591 psys->
edit =
nullptr;
5618 ot->name =
"Clear Edited";
5619 ot->idname =
"PARTICLE_OT_edited_clear";
5620 ot->description =
"Undo all edition performed on the particle system";
5650 int num_selected = 0;
5651 float total_length = 0;
5657 if (num_selected == 0) {
5660 return total_length / num_selected;
5665 float orig_prev_co[3], prev_co[3];
5691 if (point_length != 0.0f) {
5692 const float factor =
length / point_length;
5715 if (average_length == 0.0f) {
5735 ot->name =
"Unify Length";
5736 ot->idname =
"PARTICLE_OT_unify_length";
5737 ot->description =
"Make selected hair the same length";
float BKE_brush_weight_get(const Scene *scene, const Brush *brush)
void free_bvhtree_from_mesh(BVHTreeFromMesh *data)
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
@ BVHTREE_FROM_CORNER_TRIS
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmMsgBus * CTX_wm_message_bus(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
void BKE_mesh_tessface_ensure(Mesh *mesh)
ModifierData * BKE_modifiers_findby_type(const Object *ob, ModifierType type)
ModifierData * BKE_modifiers_findby_name(const Object *ob, const char *name)
ModifierData * BKE_modifier_get_evaluated(Depsgraph *depsgraph, Object *object, ModifierData *md)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
void BKE_object_minmax(Object *ob, float r_min[3], float r_max[3])
void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, struct ParticleKey *state, bool vel)
struct ParticleSystemModifierData * psys_get_modifier(struct Object *ob, struct ParticleSystem *psys)
void psys_mat_hair_to_orco(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4])
void psys_disable_all(struct Object *ob)
void psys_mat_hair_to_global(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4])
void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra)
void psys_cache_edit_paths(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra, bool use_render_params)
void psys_reset(struct ParticleSystem *psys, int mode)
void psys_mat_hair_to_object(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4])
float psys_get_timestep(struct ParticleSimulationData *sim)
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_enable_all(struct Object *ob)
@ BKE_PARTICLE_BATCH_DIRTY_ALL
void init_particle(struct ParticleSimulationData *sim, struct ParticleData *pa)
struct ParticleSystem * psys_get_current(struct Object *ob)
struct ParticleSystem * psys_eval_get(struct Depsgraph *depsgraph, struct Object *object, struct ParticleSystem *psys)
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit)
int psys_particle_dm_face_lookup(struct Mesh *mesh_final, struct Mesh *mesh_original, int findex_orig, const float fw[4], struct LinkNode **poly_nodes)
void BKE_particle_batch_cache_dirty_tag(struct ParticleSystem *psys, int mode)
#define PSYS_RESET_DEPSGRAPH
void psys_copy_particles(struct ParticleSystem *psys_dst, struct ParticleSystem *psys_src)
void BKE_ptcache_mem_pointers_incr(void *cur[BPHYS_TOT_DATA])
void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob, struct Scene *scene, int duplis)
#define PTCACHE_VEL_PER_SEC
#define PTCACHE_TYPE_CLOTH
int BKE_ptcache_mem_pointers_seek(int point_index, struct PTCacheMem *pm, void *cur[BPHYS_TOT_DATA])
#define PTCACHE_TYPE_PARTICLES
#define PTCACHE_TYPE_SOFTBODY
@ PT_CACHE_EDIT_UPDATE_PARTICLE_FROM_EVAL
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain)
#define BLI_assert_unreachable()
#define BVH_RAYCAST_DIST_MAX
void BLI_bvhtree_ray_cast_all(const BVHTree *tree, const float co[3], const float dir[3], float radius, float hit_dist, BVHTree_RayCastCallback callback, void *userdata)
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
A KD-tree for nearest neighbor search.
bool BLI_lasso_is_point_inside(blender::Span< blender::int2 > mcoords, int sx, int sy, int error_value)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void void BLI_INLINE bool BLI_listbase_is_single(const struct ListBase *lb)
MINLINE float max_ff(float a, float b)
MINLINE float interpf(float target, float origin, float t)
bool isect_aabb_aabb_v3(const float min1[3], const float max1[3], const float min2[3], const float max2[3])
bool isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], float radius, const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float ipoint[3])
bool isect_line_segment_tri_v3(const float p1[3], const float p2[3], const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2])
void interp_weights_poly_v3(float w[], float v[][3], int n, const float co[3])
void unit_m4(float m[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void mul_mat3_m4_v3(const float mat[4][4], float r[3])
MINLINE void copy_v2fl_v2i(float r[2], const int a[2])
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
void dist_ensure_v3_v3fl(float v1[3], const float v2[3], float dist)
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)
struct RNG * BLI_rng_new_srandom(unsigned int seed)
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
bool BLI_rcti_is_empty(const struct rcti *rect)
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
int BLI_task_parallel_thread_id(const TaskParallelTLS *tls)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
long int BLI_time_now_seconds_i(void)
Utility defines for timing/benchmarks.
#define SHIFT4(type, a, b, c, d)
#define INIT_MINMAX(min, max)
#define POINTER_AS_UINT(i)
#define SHIFT3(type, a, b, c)
#define SET_FLAG_FROM_TEST(value, test, flag)
void DEG_id_tag_update(ID *id, unsigned int flags)
bool DEG_is_active(const Depsgraph *depsgraph)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
#define ID_IS_EDITABLE(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
@ PE_BRUSH_DATA_PUFF_VOLUME
int * mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *mesh_eval)
void PE_free_ptcache_edit(PTCacheEdit *edit)
bool PE_hair_poll(bContext *C)
bool PE_poll(bContext *C)
bool PE_poll_view3d(bContext *C)
int ED_select_op_action_deselected(eSelectOp sel_op, bool is_select, bool is_inside)
#define SEL_OP_USE_PRE_DESELECT(sel_op)
float ED_view3d_select_dist_px()
#define XRAY_ENABLED(v3d)
@ V3D_PROJ_TEST_CLIP_NEAR
void ED_view3d_depth_override(Depsgraph *depsgraph, ARegion *region, View3D *v3d, Object *obact, eV3DDepthOverrideMode mode, bool use_overlay, ViewDepths **r_depths)
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
void ED_view3d_win_to_delta(const ARegion *region, const float xy_delta[2], float zfac, float r_out[3])
bool ED_view3d_win_to_segment_clipped(const Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_end[3], bool do_clip_planes)
void view3d_operator_needs_opengl(const bContext *C)
float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3])
void ED_view3d_depths_free(ViewDepths *depths)
void ED_view3d_project_v3(const ARegion *region, const float world[3], float r_region_co[3])
eV3DProjStatus ED_view3d_project_int_global(const ARegion *region, const float co[3], int r_co[2], eV3DProjTest flag)
@ GPU_SHADER_3D_UNIFORM_COLOR
void GPU_blend(eGPUBlend blend)
void GPU_line_smooth(bool enable)
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
#define RNA_BEGIN(sptr, itemptr, propname)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
__forceinline BoundBox intersect(const BoundBox &a, const BoundBox &b)
BPy_StructRNA * depsgraph
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
static void mul(btAlignedObjectArray< T > &items, const Q &value)
static unsigned long seed
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
static int hide_exec(bContext *C, wmOperator *op)
static int reveal_exec(bContext *C, wmOperator *op)
static int subdivide_exec(bContext *C, wmOperator *op)
static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int select_linked_exec(bContext *C, wmOperator *)
static const EnumPropertyItem delete_type_items[]
static int delete_exec(bContext *C, wmOperator *op)
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
static bool is_inside(int x, int y, int cols, int rows)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_dupallocN)(const void *vmemh)
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
bool mode_compat_set(bContext *C, Object *ob, eObjectMode mode, ReportList *reports)
void min_max(const T &value, T &min, T &max)
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< float, 3 > float3
float distance(float a, float b)
Frequency::GEOMETRY nor[]
static void rekey_particle_to_time(const bContext *C, Scene *scene, Object *ob, int pa_index, float path_time)
static void free_all_psys_edit(Object *object)
static void PE_set_data(bContext *C, PEData *data)
static int hide_exec(bContext *C, wmOperator *op)
static void PE_mirror_x(Depsgraph *depsgraph, Scene *scene, Object *ob, int tagged)
static void brush_edit_exit(wmOperator *op)
static const EnumPropertyItem select_random_type_items[]
static int brush_edit_init(bContext *C, wmOperator *op)
static bool key_inside_rect(PEData *data, const float co[3])
static int select_random_exec(bContext *C, wmOperator *op)
bool ED_object_particle_edit_mode_supported(const Object *ob)
static int select_more_exec(bContext *C, wmOperator *)
void(*)(PEData *data, int point_index) ForPointFunc
bool PE_hair_poll(bContext *C)
static int pe_x_mirror(Object *ob)
PTCacheEdit * PE_get_current_from_psys(ParticleSystem *psys)
void PARTICLE_OT_select_roots(wmOperatorType *ot)
static void foreach_mouse_hit_key_iter(void *__restrict iter_data_v, const int iter, const TaskParallelTLS *__restrict)
bool PE_poll(bContext *C)
bool PE_mouse_particles(bContext *C, const int mval[2], const SelectPick_Params *params)
bool PE_deselect_all_visible_ex(PTCacheEdit *edit)
static bool key_inside_circle(const PEData *data, float rad, const float co[3], float *distance)
static bool key_test_depth(const PEData *data, const float co[3], const int screen_co[2])
static void scale_point_to_length(PTCacheEditPoint *point, float length)
static int select_less_exec(bContext *C, wmOperator *)
static int brush_add(const bContext *C, PEData *data, short number)
static bool pe_nearest_point_and_key(bContext *C, const int mval[2], PTCacheEditPoint **r_point, PTCacheEditKey **r_key)
void PARTICLE_OT_weight_set(wmOperatorType *ot)
void PARTICLE_OT_remove_doubles(wmOperatorType *ot)
static void brush_comb(PEData *data, float[4][4], float imat[4][4], int point_index, int key_index, PTCacheEditKey *key, float mouse_distance)
static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
static void deflect_emitter_iter(void *__restrict iter_data_v, const int iter, const TaskParallelTLS *__restrict)
static void set_delete_particle(PEData *data, int pa_index)
void PARTICLE_OT_shape_cut(wmOperatorType *ot)
static int remove_doubles_exec(bContext *C, wmOperator *op)
void ED_object_particle_edit_mode_exit_ex(Scene *scene, Object *ob)
static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void brush_add_count_iter_reduce(const void *__restrict, void *__restrict join_v, void *__restrict chunk_v)
void PE_current_changed(Depsgraph *depsgraph, Scene *scene, Object *ob)
static void foreach_mouse_hit_point(PEData *data, ForHitPointFunc func, int selected)
void recalc_emitter_field(Depsgraph *, Object *, ParticleSystem *psys)
static void PE_apply_lengths(Scene *scene, PTCacheEdit *edit)
static void PE_set_view3d_data(bContext *C, PEData *data)
static float calculate_point_length(PTCacheEditPoint *point)
static void foreach_selected_key(PEData *data, ForKeyFunc func)
void PARTICLE_OT_delete(wmOperatorType *ot)
static int particle_edit_toggle_exec(bContext *C, wmOperator *op)
static void point_inside_bvh_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
static bool shape_cut_test_point(PEData *data, ParticleEditSettings *pset, ParticleCacheKey *key)
static void select_tip(PEData *data, int point_index)
void PARTICLE_OT_select_less(wmOperatorType *ot)
static void pe_select_cache_free_generic_userdata(void *data)
int PE_minmax(Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, blender::float3 &min, blender::float3 &max)
void PE_update_object(Depsgraph *depsgraph, Scene *scene, Object *ob, int useflag)
static void PE_create_random_generator(PEData *data)
void PARTICLE_OT_edited_clear(wmOperatorType *ot)
void(*)(PEData *data, int point_index, float mouse_distance) ForHitPointFunc
static bool shape_cut_poll(bContext *C)
static void select_more_keys(PEData *data, int point_index)
void(*)(PEData *data, float mat[4][4], float imat[4][4], int point_index, int key_index, PTCacheEditKey *key, float mouse_distance) ForHitKeyMatFunc
void PARTICLE_OT_mirror(wmOperatorType *ot)
static bool point_is_selected(PTCacheEditPoint *point)
static void pe_iterate_lengths(Scene *scene, PTCacheEdit *edit)
static void nearest_key_fn(PEData *data, int point_index, int key_index, bool)
void ED_object_particle_edit_mode_enter(bContext *C)
static void pe_update_hair_particle_edit_pointers(PTCacheEdit *edit)
static int brush_edit_exec(bContext *C, wmOperator *op)
static void BKE_brush_weight_get(PEData *data, float[4][4], float[4][4], int point_index, int key_index, PTCacheEditKey *, float)
static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, const enum eParticleSelectFlag flag)
void PARTICLE_OT_select_random(wmOperatorType *ot)
bool PE_poll_view3d(bContext *C)
static float calculate_average_length(PTCacheEdit *edit)
static void update_velocities(PTCacheEdit *edit)
void PARTICLE_OT_select_linked(wmOperatorType *ot)
void PARTICLE_OT_reveal(wmOperatorType *ot)
static int particle_intersect_mesh(Depsgraph *depsgraph, Scene *, Object *ob, Mesh *mesh, float *vert_cos, const float co1[3], const float co2[3], float *min_d, int *min_face, float *min_w, float *face_minmax, float *pa_minmax, float radius, float *ipoint)
static bool key_inside_test(PEData *data, const float co[3])
void PE_free_ptcache_edit(PTCacheEdit *edit)
static void foreach_point(PEData *data, ForPointFunc func)
static bool mirror_poll(bContext *C)
static void select_key(PEData *data, int point_index, int key_index, bool)
static void set_delete_particle_key(PEData *data, int pa_index, int key_index, bool)
void PARTICLE_OT_subdivide(wmOperatorType *ot)
static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
static void PE_data_free(PEData *data)
void PE_hide_keys_time(Scene *scene, PTCacheEdit *edit, float cfra)
void PE_create_particle_edit(Depsgraph *depsgraph, Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys)
static void pe_select_cache_init_with_generic_userdata(bContext *C, wmGenericUserData *wm_userdata)
static void brush_puff(PEData *data, int point_index, float mouse_distance)
static bool PE_create_shape_tree(PEData *data, Object *shapeob)
static int shape_cut_exec(bContext *C, wmOperator *)
void update_world_cos(Object *ob, PTCacheEdit *edit)
static int select_linked_pick_exec(bContext *C, wmOperator *op)
ParticleEditSettings * PE_settings(Scene *scene)
static void apply_lengths_iter(void *__restrict iter_data_v, const int iter, const TaskParallelTLS *__restrict)
static int unify_length_exec(bContext *C, wmOperator *)
void PARTICLE_OT_select_more(wmOperatorType *ot)
static int reveal_exec(bContext *C, wmOperator *op)
static int mirror_exec(bContext *C, wmOperator *)
void PARTICLE_OT_rekey(wmOperatorType *ot)
static int rekey_exec(bContext *C, wmOperator *op)
static void rekey_particle(PEData *data, int pa_index)
static void PE_free_shape_tree(PEData *data)
static int count_selected_keys(Scene *scene, PTCacheEdit *edit)
static void brush_edit_cancel(bContext *, wmOperator *op)
static int brush_edit_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void subdivide_particle(PEData *data, int pa_index)
static void select_keys(PEData *data, int point_index, int, bool)
void PARTICLE_OT_select_all(wmOperatorType *ot)
void recalc_lengths(PTCacheEdit *edit)
static int select_roots_exec(bContext *C, wmOperator *op)
static float pe_brush_size_get(const Scene *, ParticleBrushData *brush)
void PARTICLE_OT_particle_edit_toggle(wmOperatorType *ot)
static void brush_add_count_iter(void *__restrict iter_data_v, const int iter, const TaskParallelTLS *__restrict tls_v)
PTCacheEdit * PE_get_current(Depsgraph *depsgraph, Scene *scene, Object *ob)
static void brush_drawcursor(bContext *C, int x, int y, void *)
void PARTICLE_OT_select_tips(wmOperatorType *ot)
static void select_less_keys(PEData *data, int point_index)
static bool brush_edit_poll(bContext *C)
static void brush_smooth_get(PEData *data, float mat[4][4], float[4][4], int, int key_index, PTCacheEditKey *key, float)
void ED_object_particle_edit_mode_exit(bContext *C)
static void brush_length(PEData *data, int point_index, float)
int PE_lasso_select(bContext *C, const int mcoords[][2], const int mcoords_len, const int sel_op)
static void brush_smooth_do(PEData *data, float[4][4], float imat[4][4], int point_index, int key_index, PTCacheEditKey *key, float)
static int brush_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void PE_apply_mirror(Object *ob, ParticleSystem *psys)
static void toggle_particle_cursor(Scene *scene, bool enable)
static bool select_action_apply(PTCacheEditPoint *point, PTCacheEditKey *key, int action)
static void shape_cut(PEData *data, int pa_index)
int PE_start_edit(PTCacheEdit *edit)
static int delete_exec(bContext *C, wmOperator *op)
bool PE_circle_select(bContext *C, wmGenericUserData *wm_userdata, const int sel_op, const int mval[2], float rad)
static int weight_set_exec(bContext *C, wmOperator *op)
static void scale_points_to_length(PTCacheEdit *edit, float length)
static void brush_edit_apply_event(bContext *C, wmOperator *op, const wmEvent *event)
static int clear_edited_exec(bContext *C, wmOperator *)
static void select_root(PEData *data, int point_index)
static void foreach_mouse_hit_key(PEData *data, ForHitKeyMatFunc func, int selected)
static void scale_point_factor(PTCacheEditPoint *point, float factor)
void ED_object_particle_edit_mode_enter_ex(Depsgraph *depsgraph, Scene *scene, Object *ob)
static bool particle_edit_toggle_poll(bContext *C)
static void brush_add_count_iter_free(const void *__restrict, void *__restrict chunk_v)
static int select_linked_exec(bContext *C, wmOperator *)
static void brush_cut(PEData *data, int pa_index)
bool PE_box_select(bContext *C, const rcti *rect, const int sel_op)
static void remove_tagged_keys(Depsgraph *depsgraph, Object *ob, ParticleSystem *psys)
void(*)(PEData *data, int point_index, int key_index, bool is_inside) ForKeyFunc
bool PE_deselect_all_visible(bContext *C)
static void PE_mirror_particle(Object *ob, Mesh *mesh, ParticleSystem *psys, ParticleData *pa, ParticleData *mpa)
static int pe_select_all_exec(bContext *C, wmOperator *op)
static int subdivide_exec(bContext *C, wmOperator *)
static int remove_tagged_particles(Object *ob, ParticleSystem *psys, int mirror)
void PARTICLE_OT_unify_length(wmOperatorType *ot)
void PARTICLE_OT_hide(wmOperatorType *ot)
void PARTICLE_OT_select_linked_pick(wmOperatorType *ot)
static void select_key_op(PEData *data, int point_index, int key_index, bool is_inside)
static void PE_free_random_generator(PEData *data)
static PTCacheEdit * pe_get_current(Depsgraph *depsgraph, Scene *scene, Object *ob, bool create)
void(*)(PEData *data, const float mat[4][4], const float imat[4][4], int point_index, int key_index, PTCacheEditKey *key) ForKeyMatFunc
static void iterate_lengths_iter(void *__restrict iter_data_v, const int iter, const TaskParallelTLS *__restrict)
static int select_tips_exec(bContext *C, wmOperator *op)
static void intersect_dm_quad_weights(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float w[4])
static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
static void foreach_selected_point(PEData *data, ForPointFunc func)
void PARTICLE_OT_brush_edit(wmOperatorType *ot)
static void PE_update_selection(Depsgraph *depsgraph, Scene *scene, Object *ob, int useflag)
PTCacheEdit * PE_create_current(Depsgraph *depsgraph, Scene *scene, Object *ob)
#define LOOP_UNSELECTED_POINTS
#define LOOP_SELECTED_POINTS
#define LOOP_SELECTED_KEYS
#define LOOP_TAGGED_POINTS
#define LOOP_EDITED_POINTS
#define LOOP_VISIBLE_KEYS
#define LOOP_VISIBLE_POINTS
void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value)
int RNA_int_get(PointerRNA *ptr, const char *name)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_int_vector(StructOrFunctionRNA *cont_, const char *identifier, const int len, const int *default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
PropertyRNA * RNA_def_collection_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
ParticleEditSettings * pset
MeshRuntimeHandle * runtime
ObjectRuntimeHandle * runtime
BVHTreeFromMesh shape_bvh
struct PTCacheEditKey * keys
struct ParticleSystemModifierData * psmd
struct ParticleCacheKey ** pathcache
PTCacheEditPoint * points
struct ParticleSystem * psys
struct ParticleSystemModifierData * psmd_eval
struct KDTree_3d * emitter_field
struct ParticleSystem * psys_eval
struct PointCache * cache
ParticleBrushData brush[7]
struct Object * shape_object
struct Depsgraph * depsgraph
struct ParticleSystemModifierData * psmd
struct ParticleSystem * psys
struct Mesh * mesh_original
struct PTCacheEdit * edit
struct ParticleSystem * next
struct PointCache * pointcache
void(* free_edit)(struct PTCacheEdit *edit)
struct ListBase mem_cache
struct PTCacheEdit * edit
void(* free_edit)(struct PTCacheEdit *edit)
struct ToolSettings * toolsettings
TaskParallelReduceFunc func_reduce
TaskParallelFreeFunc func_free
size_t userdata_chunk_size
wmGenericUserDataFreeFn free_fn
struct ReportList * reports
void WM_main_add_notifier(uint type, void *reference)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)
int WM_operator_properties_select_random_seed_increment_get(wmOperator *op)
void WM_operator_properties_select_action(wmOperatorType *ot, int default_action, bool hide_gui)
void WM_operator_properties_select_random(wmOperatorType *ot)
void WM_operator_properties_select_all(wmOperatorType *ot)
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)
bool WM_paint_cursor_end(wmPaintCursor *handle)
int WM_operator_props_popup(bContext *C, wmOperator *op, const wmEvent *)
wmPaintCursor * WM_paint_cursor_activate(short space_type, short region_type, bool(*poll)(bContext *C), wmPaintCursorDraw draw, void *customdata)