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)) {
241 return scene->toolsettings ? &scene->toolsettings->particle :
nullptr;
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) {
390 edit->
flags &= ~PT_CACHE_EDIT_UPDATE_PARTICLE_FROM_EVAL;
426 key->flag &= ~PEK_HIDE;
438 key->flag &= ~PEK_HIDE;
512 data->edit =
PE_get_current(data->depsgraph, data->scene, data->ob);
536 data->shape_bvh = {};
561 if (data->rng !=
nullptr) {
573 data->depths =
nullptr;
585 View3D *v3d = data->vc.v3d;
607 if (screen_co[0] >= 0 && screen_co[0] < vd->
w && screen_co[1] >= 0 && screen_co[1] < vd->
h) {
610 depth = vd->
depths[screen_co[1] * vd->
w + screen_co[0]];
619 if (win[2] - 0.00001f > depth) {
637 dx = data->mval[0] - screen_co[0];
638 dy = data->mval[1] - screen_co[1];
639 dist =
sqrtf(dx * dx + dy * dy);
666 if (screen_co[0] > data->rect->xmin && screen_co[0] < data->rect->xmax &&
667 screen_co[1] > data->rect->ymin && screen_co[1] < data->rect->ymax)
710 const float mat[4][4],
711 const float imat[4][4],
721 float mouse_distance);
734 int nearest_point, nearest_key;
735 float dist = data->rad;
749 key = point->keys + point->totkey - 1;
754 nearest_key = point->totkey - 1;
760 func(data, p, point->totkey - 1,
is_inside);
786 if (nearest_point != -1) {
787 func(data, nearest_point, nearest_key,
true);
808 key = point->keys + point->totkey - 1;
810 if (selected == 0 || key->flag &
PEK_SELECT) {
811 float mouse_distance;
813 func(data, p, mouse_distance);
821 if (selected == 0 || key->flag &
PEK_SELECT) {
822 float mouse_distance;
824 func(data, p, mouse_distance);
854 const int selected = iter_data->
selected;
855 float mat[4][4], imat[4][4];
864 float mouse_distance;
871 iter_data->
func(data, mat, imat, iter, point->totkey - 1, key, mouse_distance);
882 float mouse_distance;
889 iter_data->
func(data, mat, imat, iter, k, key, mouse_distance);
907 iter_data.
edit = edit;
909 iter_data.
func = func;
934 func(data, p, k,
true);
964 key = point->keys + point->totkey - 1;
986 KDTreeNearest_3d nearest;
989 float mat[4][4], co[3];
1000 tree = BLI_kdtree_3d_new(totpart);
1009 BLI_kdtree_3d_insert(
tree, p, co);
1012 BLI_kdtree_3d_balance(
tree);
1027 index = BLI_kdtree_3d_find_nearest(
tree, co, &nearest);
1030 if (index != -1 && index != p && (nearest.dist <= 0.0002f)) {
1049 BLI_kdtree_3d_free(
tree);
1059 float mat[4][4], mmat[4][4], immat[4][4];
1085 point = edit->
points + i;
1086 mpoint = edit->
points + mi;
1100 mpoint->
totkey = point->totkey;
1103 mkey = mpoint->
keys;
1104 for (k = 0; k < mpa->
totkey; k++, mkey++, mhkey++) {
1105 mkey->
co = mhkey->
co;
1106 mkey->time = &mhkey->
time;
1107 mkey->flag &= ~PEK_SELECT;
1119 mkey = mpoint->
keys;
1120 for (k = 0; k < pa->
totkey; k++, hkey++, mhkey++, key++, mkey++) {
1123 mhkey->
co[0] = -mhkey->
co[0];
1154 if (psmd_eval ==
nullptr || psmd_eval->
mesh_final ==
nullptr) {
1216 float hairimat[4][4], hairmat[4][4];
1218 float *vec, *
nor, dvec[3],
dot, dist_1st = 0.0f;
1219 const float dist = iter_data->
dist;
1231 dist_1st *= dist * emitterdist;
1234 index = BLI_kdtree_3d_find_nearest(edit->
emitter_field, key->
co,
nullptr);
1245 if (
dot < dist_1st) {
1257 dist_1st *= 1.3333f;
1290 iter_data.
psys = psys;
1291 iter_data.
edit = edit;
1292 iter_data.
dist = dist;
1341 iter_data.
edit = edit;
1365 float dv0[3] = {0.0f, 0.0f, 0.0f};
1366 float dv1[3] = {0.0f, 0.0f, 0.0f};
1367 float dv2[3] = {0.0f, 0.0f, 0.0f};
1368 for (
int j = 1; j < point->totkey; j++) {
1371 float mul = 1.0f /
float(point->totkey);
1373 key = point->keys + 1;
1375 dv1[0] = dv1[1] = dv1[2] = 0.0;
1380 dv0[0] = dv0[1] = dv0[2] = 0.0;
1383 for (; k < point->totkey; k++, key++) {
1389 if (k < point->totkey - 1) {
1414 iter_data.
edit = edit;
1415 iter_data.
pset = pset;
1427 if (edit ==
nullptr) {
1433 for (k = 0; k < point->totkey - 1; k++, key++) {
1434 key->length =
len_v3v3(key->co, (key + 1)->co);
1456 totface = mesh->totface_legacy;
1460 MEM_callocN(
sizeof(
float[6]) * totface,
"emitter cosnos"));
1470 for (i = 0; i < totface; i++, vec += 6,
nor += 6) {
1471 const MFace *mface = &mfaces[i];
1530 point->flag &= ~PEP_EDIT_RECALC;
1542 float hairmat[4][4];
1544 if (psys ==
nullptr || psys->
edit ==
nullptr || psmd_eval ==
nullptr ||
1567 float vec1[3], vec2[3], frs_sec, dfra;
1581 dfra = *(key + 1)->time - *key->time;
1589 if (point->totkey > 2) {
1596 else if (k == point->totkey - 1) {
1597 dfra = *key->time - *(key - 1)->time;
1605 if (point->totkey > 2) {
1613 dfra = *(key + 1)->time - *(key - 1)->time;
1619 sub_v3_v3v3(key->vel, (key + 1)->co, (key - 1)->co);
1671 point->flag &= ~PEP_EDIT_RECALC;
1675 edit->
psys->
flag &= ~PSYS_HAIR_UPDATED;
1697 key->
flag &= ~PEK_SELECT;
1701 data->is_changed =
true;
1711 if (sel_op_result != -1) {
1714 data->is_changed =
true;
1729 key->flag &= ~PEK_SELECT;
1744 bool changed =
false;
1755 key->
flag &= ~PEK_SELECT;
1767 key->
flag &= ~PEK_SELECT;
1800 bool changed =
false;
1817 ot->
name =
"(De)select All";
1818 ot->
idname =
"PARTICLE_OT_select_all";
1850 user_data->
key = key;
1851 data->is_changed =
true;
1866 data.user_data = &user_data;
1868 bool found = data.is_changed;
1871 *r_point = user_data.
point;
1872 *r_key = user_data.
key;
1891 bool changed =
false;
1898 else if (found ||
params->deselect_all) {
1905 switch (
params->sel_op) {
1916 key->
flag &= ~PEK_SELECT;
1948 return changed || found;
1987 action = data.select_toggle_action;
1990 data.select_action = action;
1993 if (data.is_changed) {
2003 ot->
name =
"Select Roots";
2004 ot->
idname =
"PARTICLE_OT_select_roots";
2029 if (point->totkey == 0) {
2033 key = &point->keys[point->totkey - 1];
2060 action = data.select_toggle_action;
2063 data.select_action = action;
2066 if (data.is_changed) {
2078 ot->
name =
"Select Tips";
2079 ot->
idname =
"PARTICLE_OT_select_tips";
2104 {0,
nullptr, 0,
nullptr,
nullptr},
2153 if (data.is_changed) {
2163 ot->
name =
"Select Random";
2164 ot->
idname =
"PARTICLE_OT_select_random";
2165 ot->
description =
"Select a randomly distributed set of hair or points";
2181 "Select either hair or points");
2207 ot->
name =
"Select Linked All";
2208 ot->
idname =
"PARTICLE_OT_select_linked";
2209 ot->
description =
"Select all keys linked to already selected ones";
2228 mval[0] = location[0];
2229 mval[1] = location[1];
2253 ot->
name =
"Select Linked";
2254 ot->
idname =
"PARTICLE_OT_select_linked_pick";
2255 ot->
description =
"Select nearest particle from mouse pointer";
2267 ot->
srna,
"deselect",
false,
"Deselect",
"Deselect linked keys rather than selecting them");
2279 bool changed =
false;
2286 key->flag &= ~PEK_SELECT;
2334 bool is_changed = data.is_changed;
2378 if (wm_userdata->
data ==
nullptr) {
2392 if (data->is_changed) {
2396 return data->is_changed;
2415 float co[3], mat[4][4];
2445 const bool is_select = key->flag &
PEK_SELECT;
2450 {
reinterpret_cast<const blender::int2 *
>(mcoords), mcoords_len},
2457 if (sel_op_result != -1) {
2460 data.is_changed =
true;
2465 if (point->totkey) {
2466 key = point->keys + point->totkey - 1;
2469 const bool is_select = key->flag &
PEK_SELECT;
2474 {
reinterpret_cast<const blender::int2 *
>(mcoords), mcoords_len},
2481 if (sel_op_result != -1) {
2484 data.is_changed =
true;
2490 bool is_changed = data.is_changed;
2523 key->flag &= ~PEK_SELECT;
2533 key->flag &= ~PEK_SELECT;
2547 ot->
name =
"Hide Selected";
2560 ot->
srna,
"unselected",
false,
"Unselected",
"Hide unselected rather than selected");
2581 point->flag &= ~PEP_HIDE;
2632 else if (k == point->totkey - 1) {
2648 data->is_changed =
true;
2669 ot->
name =
"Select Less";
2670 ot->
idname =
"PARTICLE_OT_select_less";
2671 ot->
description =
"Deselect boundary selected keys of each particle";
2703 else if (k == point->totkey - 1) {
2717 key->flag &= ~PEK_TAG;
2720 data->is_changed =
true;
2741 ot->
name =
"Select More";
2742 ot->
idname =
"PARTICLE_OT_select_more";
2743 ot->
description =
"Select keys linked to boundary selected keys of each particle";
2767 HairKey *key, *new_keys, *okey;
2769 float dval, sta, end;
2773 sim.
scene = data->scene;
2779 key = new_keys =
static_cast<HairKey *
>(
2788 end = (key + data->totrekey - 1)->time = (okey + pa->
totkey - 1)->time;
2789 dval = (end - sta) /
float(data->totrekey - 1);
2792 for (k = 1, key++; k < data->totrekey - 1; k++, key++) {
2796 key->
time = sta + k * dval;
2803 pa->
hair = new_keys;
2805 point->totkey = pa->
totkey = data->totrekey;
2813 for (k = 0, key = pa->
hair; k < pa->
totkey; k++, key++, ekey++) {
2822 pa->
flag &= ~PARS_REKEY;
2832 data.dval = 1.0f /
float(data.totrekey - 1);
2849 ot->
description =
"Change the number of keys of selected particles (root and tip keys included)";
2860 RNA_def_int(
ot->
srna,
"keys_number", 2, 2, INT_MAX,
"Number of Keys",
"", 2, 100);
2876 if (!edit || !edit->
psys) {
2894 for (k = 1, key++; k < pa->
totkey; k++, key++) {
2904 pa->
hair = new_keys;
2914 pa->
flag &= ~PARS_REKEY;
2930 int i, new_totpart = psys->
totpart, removed = 0;
2946 if (new_totpart != psys->
totpart) {
2953 if (
ELEM(
nullptr, new_pars, new_points)) {
2967 for (i = 0; i < psys->
totpart; i++, pa++, point++) {
2992 edit->
points = new_points;
2998 psys->
child =
nullptr;
3012 HairKey *hkey, *nhkey, *new_hkeys =
nullptr;
3033 new_totkey = point->totkey;
3038 if (new_totkey < 2) {
3052 if (new_totkey != pa->
totkey) {
3053 nhkey = new_hkeys =
static_cast<HairKey *
>(
3060 while (key->flag &
PEK_TAG && hkey < pa->hair + pa->
totkey) {
3065 if (hkey < pa->hair + pa->
totkey) {
3071 nkey->
co = nhkey->
co;
3074 nkey->
flag = key->flag;
3075 nkey->
ftime = key->ftime;
3076 nkey->
length = key->length;
3092 pa->
hair = new_hkeys;
3093 point->keys = new_keys;
3095 point->totkey = pa->
totkey = new_totkey;
3118 HairKey *key, *nkey, *new_keys;
3122 short totnewkey = 0;
3126 sim.
scene = data->scene;
3130 for (k = 0, ekey = point->keys; k < pa->
totkey - 1; k++, ekey++) {
3136 if (totnewkey == 0) {
3142 nkey = new_keys =
static_cast<HairKey *
>(
3150 for (k = 0, ekey = point->keys; k < pa->
totkey - 1; k++, key++, ekey++) {
3152 memcpy(nkey, key,
sizeof(
HairKey));
3155 nekey->
co = nkey->
co;
3162 nkey->
time = (key->
time + (key + 1)->time) * 0.5f;
3163 state.time = (endtime != 0.0f) ? nkey->
time / endtime : 0.0f;
3167 nekey->
co = nkey->
co;
3179 memcpy(nkey, key,
sizeof(
HairKey));
3182 nekey->
co = nkey->
co;
3188 pa->
hair = new_keys;
3193 point->keys = new_ekeys;
3197 pa->
flag &= ~PARS_REKEY;
3220 ot->
idname =
"PARTICLE_OT_subdivide";
3221 ot->
description =
"Subdivide selected particles segments (adds keys)";
3246 KDTreeNearest_3d nearest[10];
3249 int n, totn, removed, totremoved;
3270 BLI_kdtree_3d_insert(
tree, p, co);
3273 BLI_kdtree_3d_balance(
tree);
3282 totn = BLI_kdtree_3d_find_nearest_n(
tree, co, nearest, 10);
3284 for (n = 0; n < totn; n++) {
3286 if (nearest[n].index > p && nearest[n].dist < threshold) {
3287 if (!(point->flag &
PEP_TAG)) {
3295 BLI_kdtree_3d_free(
tree);
3299 totremoved += removed;
3302 if (totremoved == 0) {
3317 ot->
name =
"Remove Doubles";
3318 ot->
idname =
"PARTICLE_OT_remove_doubles";
3319 ot->
description =
"Remove selected particles close enough of others";
3335 "Threshold distance within which particles are removed",
3362 hkey = pa->
hair + k;
3377 ot->
idname =
"PARTICLE_OT_weight_set";
3393 "Interpolation factor between current brush weight, and keys' weights",
3458 {
DEL_KEY,
"KEY", 0,
"Key",
""},
3459 {0,
nullptr, 0,
nullptr,
nullptr},
3522 "Delete a full particle or only keys");
3542 int *mirrorfaces =
nullptr;
3543 int rotation, totpart, newtotpart;
3563 ob,
nullptr, use_dm_final_indices ? psmd_eval->
mesh_final :
nullptr);
3585 if ((point->flag &
PEP_TAG) && mirrorfaces[pa->
num * 2] != -1) {
3590 if (newtotpart != psys->
totpart) {
3591 const MFace *mtessface = use_dm_final_indices ?
3613 edit->
points = new_points;
3621 newpoint = edit->
points + totpart;
3623 for (p = 0, point = edit->
points; p < totpart; p++, point++) {
3625 const int pa_num = pa->
num;
3631 if (!(point->flag &
PEP_TAG) || mirrorfaces[pa_num * 2] == -1) {
3646 rotation = mirrorfaces[pa_num * 2 + 1];
3647 newpa->
fuv[0] = pa->
fuv[2];
3648 newpa->
fuv[1] = pa->
fuv[1];
3649 newpa->
fuv[2] = pa->
fuv[0];
3650 newpa->
fuv[3] = pa->
fuv[3];
3651 while (rotation--) {
3652 if (mtessface[pa_num].v4) {
3663 newpa->
num = mirrorfaces[pa_num * 2];
3665 if (use_dm_final_indices) {
3674 key = newpoint->
keys;
3675 for (k = 0, hkey = newpa->
hair; k < newpa->
totkey; k++, hkey++, key++) {
3677 key->time = &hkey->time;
3689 point->
flag &= ~PEP_TAG;
3734 ot->
description =
"Duplicate and mirror the selected particles along the local X axis";
3756 float mouse_distance)
3765 fac =
float(
pow(
double(1.0f - mouse_distance / data->rad),
double(data->combfac)));
3778 ARegion *region = data->vc.region;
3782 float rad2, cut_time = 1.0;
3783 float x0, x1, v0, v1, o0, o1, xo0, xo1, d, dv;
3804 rad2 = data->rad * data->rad;
3808 x0 =
float(screen_co[0]);
3809 x1 =
float(screen_co[1]);
3811 o0 =
float(data->mval[0]);
3812 o1 =
float(data->mval[1]);
3818 if (xo0 * xo0 + xo1 * xo1 < rad2 &&
key_test_depth(data, key->
co, screen_co)) {
3824 for (k = 1, key++; k <= keys; k++, key++) {
3830 x0 =
float(screen_co[0]);
3831 x1 =
float(screen_co[1]);
3838 v0 =
float(screen_co[0]) - x0;
3839 v1 =
float(screen_co[1]) - x1;
3841 dv = v0 * v0 + v1 * v1;
3843 d = (v0 * xo1 - v1 * xo0);
3845 d = dv * rad2 - d * d;
3850 cut_time = -(v0 * xo0 + v1 * xo1 + d);
3852 if (cut_time > 0.0f) {
3855 if (cut_time < 1.0f) {
3856 cut_time +=
float(k - 1);
3857 cut_time /=
float(keys);
3864 x0 =
float(screen_co[0]);
3865 x1 =
float(screen_co[1]);
3873 if (cut_time < 0.0f) {
3888 float dvec[3], pvec[3] = {0.0f, 0.0f, 0.0f};
3911 float mat[4][4], imat[4][4];
3915 float co_root[3], no_root[3];
3916 float co_prev[3], co[3];
3917 float fac = 0.0f, length_accum = 0.0f;
3918 bool puff_volume =
false;
3919 bool changed =
false;
3949 mul_v3_m4v3(kco, data->ob->world_to_object().ptr(), co);
3951 point_index = BLI_kdtree_3d_find_nearest(edit->
emitter_field, kco,
nullptr);
3952 if (point_index == -1) {
3967 fac =
float(
pow(
double(1.0f - mouse_distance / data->rad),
double(data->pufffac)));
4033 float oco[3], onor[3];
4039 mul_v3_m4v3(kco, data->ob->world_to_object().ptr(), oco);
4041 point_index = BLI_kdtree_3d_find_nearest(edit->
emitter_field, kco,
nullptr);
4042 if (point_index != -1) {
4087 pa->
hair[key_index].
weight = data->weightfac;
4119 float vec[3], dvec[3];
4138 const float v1[3],
const float v2[3],
const float v3[3],
const float v4[3],
float w[4])
4140 float co[3], vert[4][3];
4147 co[0] = v1[0] *
w[0] +
v2[0] *
w[1] + v3[0] *
w[2] + v4[0] *
w[3];
4148 co[1] = v1[1] *
w[0] +
v2[1] *
w[1] + v3[1] *
w[2] + v4[1] *
w[3];
4149 co[2] = v1[2] *
w[0] +
v2[2] *
w[1] + v3[2] *
w[2] + v4[2] *
w[3];
4170 const MFace *mface =
nullptr;
4175 float cur_ipoint[3];
4177 if (mesh ==
nullptr) {
4182 if (mesh ==
nullptr) {
4188 if (mesh ==
nullptr) {
4196 if (pa_minmax ==
nullptr) {
4206 totface = mesh->totface_legacy;
4211 for (i = 0; i < totface; i++, mface++) {
4229 if (face_minmax ==
nullptr) {
4249 if (radius > 0.0f) {
4251 if (cur_d < *min_d) {
4260 if (cur_d < *min_d) {
4271 if (cur_d < *min_d) {
4273 min_w[0] = 1.0f - cur_uv[0] - cur_uv[1];
4274 min_w[1] = cur_uv[0];
4275 min_w[2] = cur_uv[1];
4286 if (cur_d < *min_d) {
4288 min_w[0] = 1.0f - cur_uv[0] - cur_uv[1];
4290 min_w[2] = cur_uv[0];
4291 min_w[3] = cur_uv[1];
4332 const int number = iter_data->
number;
4333 const short size = iter_data->
size;
4334 const int size2 = size *
size;
4339 if (tls->
rng ==
nullptr) {
4344 while (dmx * dmx + dmy * dmy > size2) {
4355 mco[0] = data->mval[0] + dmx;
4356 mco[1] = data->mval[1] + dmy;
4358 float co1[3], co2[3];
4406 void *__restrict join_v,
4407 void *__restrict chunk_v)
4415 void *__restrict chunk_v)
4418 if (tls->
rng !=
nullptr) {
4426 Scene *scene = data->scene;
4435 int i, k, n = 0, totpart = psys->
totpart;
4436 float co1[3], imat[4][4];
4437 float framestep, timestep;
4456 sim.
psmd = psmd_eval;
4479 iter_data.
number = number;
4488 settings.userdata_chunk = &tls;
4498 for (
int current_iter = 0, new_index = 0; current_iter < number; current_iter++) {
4502 if (new_index != current_iter) {
4506 memcpy(add_pars + new_index, add_pars + current_iter,
sizeof(
ParticleData));
4512 int newtotpart = totpart + n;
4513 float hairmat[4][4], cur_co[3];
4514 KDTree_3d *
tree =
nullptr;
4536 edit->
points = new_points;
4544 for (i = 0, pa = psys->
particles; i < totpart; i++, pa++) {
4556 BLI_kdtree_3d_insert(
tree, i, cur_co);
4559 BLI_kdtree_3d_balance(
tree);
4566 point = edit->
points + totpart;
4568 for (i = totpart; i < newtotpart; i++, pa++, point++) {
4569 memcpy(pa, add_pars + i - totpart,
sizeof(
ParticleData));
4576 for (k = 0, hkey = pa->
hair; k < pa->
totkey; k++, hkey++, key++) {
4578 key->
time = &hkey->time;
4599 KDTreeNearest_3d ptn[3];
4601 float maxd, totw = 0.0, weight[3];
4614 maxw = BLI_kdtree_3d_find_nearest_n(
tree, co1, ptn, 3);
4616 maxd = ptn[maxw - 1].dist;
4618 for (
w = 0;
w < maxw;
w++) {
4619 weight[
w] =
float(
pow(2.0,
double(-6.0f * ptn[
w].dist / maxd)));
4622 for (;
w < 3;
w++) {
4627 for (
w = 0;
w < maxw;
w++) {
4632 for (
w = 0;
w < maxw;
w++) {
4633 weight[
w] = 1.0f / maxw;
4641 thkey->
time = pa->
time + k * framestep;
4643 key3[0].
time = thkey->
time / 100.0f;
4674 for (k = 0, hkey = pa->
hair; k < pset->
totaddkey; k++, hkey++) {
4676 hkey->time += k * framestep;
4680 for (k = 0, hkey = pa->
hair; k < pset->
totaddkey; k++, hkey++) {
4688 BLI_kdtree_3d_free(
tree);
4764 float vec[3], mousef[2];
4766 int flip, mouse[2], removed = 0, added = 0, selected = 0, tot_steps = 1, step = 1;
4775 mouse[0] = mousef[0];
4776 mouse[1] = mousef[1];
4792 pset->
flag &= ~PE_LOCK_FIRST;
4797 (dx != 0 || dy != 0)) ||
4809 dx /=
float(tot_steps);
4810 dy /=
float(tot_steps);
4812 for (step = 1; step <= tot_steps; step++) {
4813 mval[0] = bedit->
lastmouse[0] + step * dx;
4814 mval[1] = bedit->
lastmouse[1] + step * dy;
4818 const float xy_delta[2] = {dx, dy};
4822 data.combfac = (brush->
strength - 0.5f) * 2.0f;
4823 if (data.combfac < 0.0f) {
4824 data.combfac = 1.0f - 9.0f * data.combfac;
4827 data.combfac = 1.0f - data.combfac;
4866 data.growfac = brush->
strength / 50.0f;
4868 if (brush->
invert ^ flip) {
4869 data.growfac = 1.0f - data.growfac;
4872 data.growfac = 1.0f + data.growfac;
4887 data.select = selected;
4889 data.pufffac = (brush->
strength - 0.5f) * 2.0f;
4890 if (data.pufffac < 0.0f) {
4891 data.pufffac = 1.0f - 9.0f * data.pufffac;
4894 data.pufffac = 1.0f - data.pufffac;
4897 data.invert = (brush->
invert ^ flip);
4923 data.vec[0] = data.vec[1] = data.vec[2] = 0.0f;
4933 mul_v3_fl(data.vec, 1.0f /
float(data.tot));
4986 pset->
flag |= lock_root;
5045 switch (event->
type) {
5076 ot->
idname =
"PARTICLE_OT_brush_edit";
5077 ot->
description =
"Apply a stroke of brush to the particles";
5129 if (hit->index != -1) {
5138 const float dir[3] = {1.0f, 0.0f, 0.0f};
5141 userdata.
bvhdata = data->shape_bvh;
5151 return (userdata.
num_hits % 2) == 1;
5162 float cut_time = 1.0;
5179 for (k = 0; k < totkeys; k++, key++) {
5182 float co_curr_shape[3], co_next_shape[3];
5189 sub_v3_v3v3(dir_shape, co_next_shape, co_curr_shape);
5192 memset(&hit, 0,
sizeof(hit));
5194 hit.dist = len_shape;
5200 data->shape_bvh.raycast_callback,
5202 if (hit.index >= 0) {
5203 if (hit.dist < len_shape) {
5204 cut_time = ((hit.dist / len_shape) +
float(k)) /
float(totkeys);
5213 if (cut_time < 0.0f) {
5240 pset->
flag &= ~PE_LOCK_FIRST;
5285 pset->
flag |= lock_root;
5294 ot->
idname =
"PARTICLE_OT_shape_cut";
5295 ot->
description =
"Cut hair to conform to the set shape object";
5324 if (psmd !=
nullptr) {
5330 if (!(psys && psmd && psmd_eval->
mesh_final) && !cache) {
5342 edit = (psys) ? psys->
edit : cache->
edit;
5358 if (psys && !cache) {
5380 key->time = &hkey->
time;
5398 edit->
psys =
nullptr;
5411 if (!point->totkey) {
5417 key = point->keys + point->totkey;
5423 key->ftime =
float(pm->frame);
5424 key->time = &key->ftime;
5434 if (psys && !cache) {
5462 if (psys->edit !=
nullptr) {
5464 psys->free_edit(psys->edit);
5465 psys->free_edit =
nullptr;
5466 psys->edit =
nullptr;
5491 if (edit && edit->
psys) {
5516 ob->
mode &= ~OB_MODE_PARTICLE_EDIT;
5537 const bool is_mode_set = (ob->
mode & mode_flag) != 0;
5563 ot->
name =
"Particle Edit Toggle";
5564 ot->
idname =
"PARTICLE_OT_particle_edit_toggle";
5590 psys->
edit =
nullptr;
5594 psys->
flag &= ~PSYS_GLOBAL_HAIR;
5595 psys->
flag &= ~PSYS_EDITED;
5605 psys->
flag &= ~PSYS_GLOBAL_HAIR;
5606 psys->
flag &= ~PSYS_EDITED;
5617 ot->
name =
"Clear Edited";
5618 ot->
idname =
"PARTICLE_OT_edited_clear";
5619 ot->
description =
"Undo all edition performed on the particle system";
5637 float length = 0.0f;
5641 length +=
len_v3v3((key - 1)->co, key->co);
5649 int num_selected = 0;
5650 float total_length = 0;
5656 if (num_selected == 0) {
5659 return total_length / num_selected;
5664 float orig_prev_co[3], prev_co[3];
5690 if (point_length != 0.0f) {
5691 const float factor = length / point_length;
5714 if (average_length == 0.0f) {
5734 ot->
name =
"Unify Length";
5735 ot->
idname =
"PARTICLE_OT_unify_length";
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)
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)
@ BKE_PARTICLE_BATCH_DIRTY_ALL
void BKE_ptcache_mem_pointers_incr(void *cur[BPHYS_TOT_DATA])
@ PT_CACHE_EDIT_UPDATE_PARTICLE_FROM_EVAL
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
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)
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
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
void ED_view3d_depth_override(Depsgraph *depsgraph, ARegion *region, View3D *v3d, Object *obact, eV3DDepthOverrideMode mode, ViewDepths **r_depths)
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)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
static void mul(btAlignedObjectArray< T > &items, const Q &value)
static unsigned long seed
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
const Depsgraph * depsgraph
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)
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 const EnumPropertyItem delete_type_items[]
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)
BVHTree_RayCastCallback raycast_callback
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 PointCache * pointcache
void(* free_edit)(struct PTCacheEdit *edit)
struct ListBase mem_cache
struct PTCacheEdit * edit
void(* free_edit)(struct PTCacheEdit *edit)
wmGenericUserDataFreeFn free_fn
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
void(* cancel)(bContext *C, wmOperator *op)
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)