97 if (edit ==
nullptr) {
118 if (edit ==
nullptr || edit->
psys ==
nullptr) {
141 if (edit ==
nullptr) {
187 float co[3], mat[4][4];
194 if ((psys = edit->
psys)) {
278 for (
int p = 0; p < edit->
totpoint; p++) {
281 for (
int k = 0; k < point->
totkey; k++) {
283 key->
co = hair_key->
co;
307 if (pset ==
nullptr || ob ==
nullptr) {
345 if (create && !psys->
edit) {
544 data->shape_bvh = MEM_new<blender::bke::BVHTreeFromMesh>(__func__, mesh->bvh_corner_tris());
545 return data->shape_bvh->tree !=
nullptr;
550 MEM_delete(
data->shape_bvh);
563 if (
data->rng !=
nullptr) {
575 data->depths =
nullptr;
609 if (screen_co[0] >= 0 && screen_co[0] < vd->
w && screen_co[1] >= 0 && screen_co[1] < vd->
h) {
612 depth = vd->
depths[screen_co[1] * vd->
w + screen_co[0]];
621 if (win[2] - 0.00001f > depth) {
639 dx =
data->mval[0] - screen_co[0];
640 dy =
data->mval[1] - screen_co[1];
641 dist =
sqrtf(dx * dx + dy * dy);
668 if (screen_co[0] >
data->rect->xmin && screen_co[0] <
data->rect->xmax &&
669 screen_co[1] >
data->rect->ymin && screen_co[1] <
data->rect->ymax)
712 const float mat[4][4],
713 const float imat[4][4],
723 float mouse_distance);
736 int nearest_point, nearest_key;
737 float dist =
data->rad;
751 key = point->keys + point->totkey - 1;
756 nearest_key = point->totkey - 1;
788 if (nearest_point != -1) {
789 func(
data, nearest_point, nearest_key,
true);
810 key = point->keys + point->totkey - 1;
812 if (selected == 0 || key->flag &
PEK_SELECT) {
813 float mouse_distance;
815 func(
data, p, mouse_distance);
823 if (selected == 0 || key->flag &
PEK_SELECT) {
824 float mouse_distance;
826 func(
data, p, mouse_distance);
856 const int selected = iter_data->
selected;
857 float mat[4][4], imat[4][4];
866 float mouse_distance;
873 iter_data->
func(
data, mat, imat, iter, point->
totkey - 1, key, mouse_distance);
884 float mouse_distance;
891 iter_data->
func(
data, mat, imat, iter, k, key, mouse_distance);
909 iter_data.
edit = edit;
911 iter_data.
func = func;
936 func(
data, p, k,
true);
966 key = point->keys + point->totkey - 1;
988 KDTreeNearest_3d nearest;
991 float mat[4][4], co[3];
1002 tree = BLI_kdtree_3d_new(totpart);
1011 BLI_kdtree_3d_insert(
tree, p, co);
1014 BLI_kdtree_3d_balance(
tree);
1029 index = BLI_kdtree_3d_find_nearest(
tree, co, &nearest);
1032 if (index != -1 && index != p && (nearest.dist <= 0.0002f)) {
1051 BLI_kdtree_3d_free(
tree);
1061 float mat[4][4], mmat[4][4], immat[4][4];
1088 mpoint = edit->
points + mi;
1105 mkey = mpoint->
keys;
1106 for (k = 0; k < mpa->
totkey; k++, mkey++, mhkey++) {
1107 mkey->co = mhkey->
co;
1108 mkey->time = &mhkey->
time;
1121 mkey = mpoint->
keys;
1122 for (k = 0; k < pa->
totkey; k++, hkey++, mhkey++, key++, mkey++) {
1125 mhkey->
co[0] = -mhkey->
co[0];
1156 if (psmd_eval ==
nullptr || psmd_eval->
mesh_final ==
nullptr) {
1218 float hairimat[4][4], hairmat[4][4];
1220 float *vec, *
nor, dvec[3],
dot, dist_1st = 0.0f;
1221 const float dist = iter_data->
dist;
1233 dist_1st *= dist * emitterdist;
1236 index = BLI_kdtree_3d_find_nearest(edit->
emitter_field, key->
co,
nullptr);
1247 if (
dot < dist_1st) {
1259 dist_1st *= 1.3333f;
1292 iter_data.
psys = psys;
1293 iter_data.
edit = edit;
1294 iter_data.
dist = dist;
1343 iter_data.
edit = edit;
1367 float dv0[3] = {0.0f, 0.0f, 0.0f};
1368 float dv1[3] = {0.0f, 0.0f, 0.0f};
1369 float dv2[3] = {0.0f, 0.0f, 0.0f};
1370 for (
int j = 1; j < point->
totkey; j++) {
1375 key = point->
keys + 1;
1377 dv1[0] = dv1[1] = dv1[2] = 0.0;
1382 dv0[0] = dv0[1] = dv0[2] = 0.0;
1385 for (; k < point->
totkey; k++, key++) {
1391 if (k < point->totkey - 1) {
1416 iter_data.
edit = edit;
1417 iter_data.
pset = pset;
1429 if (edit ==
nullptr) {
1435 for (k = 0; k < point->totkey - 1; k++, key++) {
1436 key->length =
len_v3v3(key->co, (key + 1)->co);
1462 MEM_callocN(
sizeof(
float[6]) * totface,
"emitter cosnos"));
1472 for (
i = 0;
i < totface;
i++, vec += 6,
nor += 6) {
1473 const MFace *mface = &mfaces[
i];
1544 float hairmat[4][4];
1546 if (psys ==
nullptr || psys->
edit ==
nullptr || psmd_eval ==
nullptr ||
1569 float vec1[3], vec2[3], frs_sec, dfra;
1583 dfra = *(key + 1)->time - *key->time;
1591 if (point->totkey > 2) {
1598 else if (k == point->totkey - 1) {
1599 dfra = *key->time - *(key - 1)->time;
1607 if (point->totkey > 2) {
1615 dfra = *(key + 1)->time - *(key - 1)->time;
1621 sub_v3_v3v3(key->vel, (key + 1)->co, (key - 1)->co);
1703 data->is_changed =
true;
1713 if (sel_op_result != -1) {
1716 data->is_changed =
true;
1746 bool changed =
false;
1802 bool changed =
false;
1819 ot->name =
"(De)select All";
1820 ot->idname =
"PARTICLE_OT_select_all";
1821 ot->description =
"(De)select all particles' keys";
1851 user_data->
point = point;
1852 user_data->
key = key;
1853 data->is_changed =
true;
1868 data.user_data = &user_data;
1870 bool found =
data.is_changed;
1873 *r_point = user_data.
point;
1874 *r_key = user_data.
key;
1893 bool changed =
false;
1900 else if (found ||
params.deselect_all) {
1950 return changed || found;
1989 action =
data.select_toggle_action;
1992 data.select_action = action;
1995 if (
data.is_changed) {
2005 ot->name =
"Select Roots";
2006 ot->idname =
"PARTICLE_OT_select_roots";
2007 ot->description =
"Select roots of all visible particles";
2031 if (point->
totkey == 0) {
2062 action =
data.select_toggle_action;
2065 data.select_action = action;
2068 if (
data.is_changed) {
2080 ot->name =
"Select Tips";
2081 ot->idname =
"PARTICLE_OT_select_tips";
2082 ot->description =
"Select tips of all visible particles";
2106 {0,
nullptr, 0,
nullptr,
nullptr},
2155 if (
data.is_changed) {
2165 ot->name =
"Select Random";
2166 ot->idname =
"PARTICLE_OT_select_random";
2167 ot->description =
"Select a randomly distributed set of hair or points";
2183 "Select either hair or points");
2209 ot->name =
"Select Linked All";
2210 ot->idname =
"PARTICLE_OT_select_linked";
2211 ot->description =
"Select all keys linked to already selected ones";
2230 mval[0] = location[0];
2231 mval[1] = location[1];
2257 ot->name =
"Select Linked";
2258 ot->idname =
"PARTICLE_OT_select_linked_pick";
2259 ot->description =
"Select nearest particle from mouse pointer";
2271 ot->srna,
"deselect",
false,
"Deselect",
"Deselect linked keys rather than selecting them");
2283 bool changed =
false;
2338 bool is_changed =
data.is_changed;
2382 if (wm_userdata->
data ==
nullptr) {
2396 if (
data->is_changed) {
2400 return data->is_changed;
2419 float co[3], mat[4][4];
2449 const bool is_select = key->flag &
PEK_SELECT;
2454 {
reinterpret_cast<const blender::int2 *
>(mcoords), mcoords_len},
2461 if (sel_op_result != -1) {
2464 data.is_changed =
true;
2469 if (point->totkey) {
2470 key = point->keys + point->totkey - 1;
2473 const bool is_select = key->flag &
PEK_SELECT;
2478 {
reinterpret_cast<const blender::int2 *
>(mcoords), mcoords_len},
2485 if (sel_op_result != -1) {
2488 data.is_changed =
true;
2494 bool is_changed =
data.is_changed;
2551 ot->name =
"Hide Selected";
2552 ot->idname =
"PARTICLE_OT_hide";
2553 ot->description =
"Hide selected particles";
2564 ot->srna,
"unselected",
false,
"Unselected",
"Hide unselected rather than selected");
2603 ot->name =
"Reveal";
2604 ot->idname =
"PARTICLE_OT_reveal";
2605 ot->description =
"Show hidden particles";
2636 else if (k == point->
totkey - 1) {
2652 data->is_changed =
true;
2673 ot->name =
"Select Less";
2674 ot->idname =
"PARTICLE_OT_select_less";
2675 ot->description =
"Deselect boundary selected keys of each particle";
2707 else if (k == point->
totkey - 1) {
2724 data->is_changed =
true;
2745 ot->name =
"Select More";
2746 ot->idname =
"PARTICLE_OT_select_more";
2747 ot->description =
"Select keys linked to boundary selected keys of each particle";
2771 HairKey *key, *new_keys, *okey;
2773 float dval, sta, end;
2791 end = (key +
data->totrekey - 1)->time = (okey + pa->
totkey - 1)->time;
2792 dval = (end - sta) /
float(
data->totrekey - 1);
2795 for (k = 1, key++; k <
data->totrekey - 1; k++, key++) {
2799 key->
time = sta + k * dval;
2804 pa->
hair = new_keys;
2813 for (k = 0, key = pa->
hair; k < pa->totkey; k++, key++, ekey++) {
2848 ot->idname =
"PARTICLE_OT_rekey";
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;
2907 for (k = 0, key = pa->
hair, ekey = edit->
points[pa_index].
keys; k < pa->totkey;
2930 int i, new_totpart = psys->
totpart, removed = 0;
2946 if (new_totpart != psys->
totpart) {
2950 "PTCacheEditKey array");
2952 if (
ELEM(
nullptr, new_pars, new_points)) {
2966 for (
i = 0;
i < psys->
totpart;
i++, pa++, point++) {
2991 edit->
points = new_points;
2997 psys->
child =
nullptr;
3011 HairKey *hkey, *nhkey, *new_hkeys =
nullptr;
3032 new_totkey = point->totkey;
3037 if (new_totkey < 2) {
3051 if (new_totkey != pa->
totkey) {
3057 while (key->flag &
PEK_TAG && hkey < pa->hair + pa->
totkey) {
3062 if (hkey < pa->hair + pa->
totkey) {
3068 nkey->
co = nhkey->
co;
3071 nkey->
flag = key->flag;
3072 nkey->
ftime = key->ftime;
3073 nkey->
length = key->length;
3089 pa->
hair = new_hkeys;
3090 point->keys = new_keys;
3092 point->totkey = pa->
totkey = new_totkey;
3115 HairKey *key, *nkey, *new_keys;
3119 short totnewkey = 0;
3127 for (k = 0, ekey = point->
keys; k < pa->totkey - 1; k++, ekey++) {
3133 if (totnewkey == 0) {
3141 "Hair subdivide edit keys");
3146 for (k = 0, ekey = point->
keys; k < pa->totkey - 1; k++, key++, ekey++) {
3148 memcpy(nkey, key,
sizeof(
HairKey));
3151 nekey->
co = nkey->
co;
3158 nkey->
time = (key->
time + (key + 1)->time) * 0.5f;
3159 state.time = (endtime != 0.0f) ? nkey->
time / endtime : 0.0f;
3163 nekey->
co = nkey->
co;
3175 memcpy(nkey, key,
sizeof(
HairKey));
3178 nekey->
co = nkey->
co;
3182 pa->
hair = new_keys;
3187 point->
keys = new_ekeys;
3213 ot->name =
"Subdivide";
3214 ot->idname =
"PARTICLE_OT_subdivide";
3215 ot->description =
"Subdivide selected particles segments (adds keys)";
3240 KDTreeNearest_3d nearest[10];
3243 int n, totn, removed, totremoved;
3264 BLI_kdtree_3d_insert(
tree, p, co);
3267 BLI_kdtree_3d_balance(
tree);
3276 totn = BLI_kdtree_3d_find_nearest_n(
tree, co, nearest, 10);
3278 for (n = 0; n < totn; n++) {
3280 if (nearest[n].index > p && nearest[n].dist < threshold) {
3281 if (!(point->flag &
PEP_TAG)) {
3289 BLI_kdtree_3d_free(
tree);
3293 totremoved += removed;
3296 if (totremoved == 0) {
3311 ot->name =
"Remove Doubles";
3312 ot->idname =
"PARTICLE_OT_remove_doubles";
3313 ot->description =
"Remove selected particles close enough of others";
3329 "Threshold distance within which particles are removed",
3356 hkey = pa->
hair + k;
3370 ot->name =
"Weight Set";
3371 ot->idname =
"PARTICLE_OT_weight_set";
3372 ot->description =
"Set the weight of selected keys";
3387 "Interpolation factor between current brush weight, and keys' weights",
3456 {
DEL_KEY,
"KEY", 0,
"Key",
""},
3457 {0,
nullptr, 0,
nullptr,
nullptr},
3502 ot->name =
"Delete";
3503 ot->idname =
"PARTICLE_OT_delete";
3504 ot->description =
"Delete selected particles or keys";
3520 "Delete a full particle or only keys");
3540 int *mirrorfaces =
nullptr;
3541 int rotation, totpart, newtotpart;
3561 ob,
nullptr, use_dm_final_indices ? psmd_eval->
mesh_final :
nullptr);
3583 if ((point->flag &
PEP_TAG) && mirrorfaces[pa->
num * 2] != -1) {
3588 if (newtotpart != psys->
totpart) {
3589 const MFace *mtessface = use_dm_final_indices ?
3609 edit->
points = new_points;
3617 newpoint = edit->
points + totpart;
3619 for (p = 0, point = edit->
points; p < totpart; p++, point++) {
3621 const int pa_num = pa->
num;
3627 if (!(point->flag &
PEP_TAG) || mirrorfaces[pa_num * 2] == -1) {
3642 rotation = mirrorfaces[pa_num * 2 + 1];
3643 newpa->
fuv[0] = pa->
fuv[2];
3644 newpa->
fuv[1] = pa->
fuv[1];
3645 newpa->
fuv[2] = pa->
fuv[0];
3646 newpa->
fuv[3] = pa->
fuv[3];
3647 while (rotation--) {
3648 if (mtessface[pa_num].v4) {
3659 newpa->
num = mirrorfaces[pa_num * 2];
3661 if (use_dm_final_indices) {
3670 key = newpoint->
keys;
3671 for (k = 0, hkey = newpa->
hair; k < newpa->totkey; k++, hkey++, key++) {
3673 key->time = &hkey->
time;
3728 ot->name =
"Mirror";
3733 ot->idname =
"PARTICLE_OT_mirror";
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)));
3782 float rad2, cut_time = 1.0;
3783 float x0, x1, v0, v1, o0, o1, xo0, xo1, d, dv;
3784 int k, cut, keys = int(
pow(2.0,
double(pset->
draw_step)));
3808 x0 =
float(screen_co[0]);
3809 x1 =
float(screen_co[1]);
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;
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];
4041 point_index = BLI_kdtree_3d_find_nearest(edit->
emitter_field, kco,
nullptr);
4042 if (point_index != -1) {
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) {
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;
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) {
4435 int i, k, n = 0, totpart = psys->
totpart;
4436 float co1[3], imat[4][4];
4437 float framestep, timestep;
4455 sim.
psmd = psmd_eval;
4474 iter_data.
scene = scene;
4476 iter_data.
mesh = mesh;
4478 iter_data.
number = number;
4497 for (
int current_iter = 0, new_index = 0; current_iter < number; current_iter++) {
4501 if (new_index != current_iter) {
4505 memcpy(add_pars + new_index, add_pars + current_iter,
sizeof(
ParticleData));
4511 int newtotpart = totpart + n;
4512 float hairmat[4][4], cur_co[3];
4513 KDTree_3d *
tree =
nullptr;
4516 newtotpart,
"PTCacheEditPoint array new");
4533 edit->
points = new_points;
4541 for (
i = 0, pa = psys->
particles;
i < totpart;
i++, pa++) {
4553 BLI_kdtree_3d_insert(
tree,
i, cur_co);
4556 BLI_kdtree_3d_balance(
tree);
4563 point = edit->
points + totpart;
4565 for (
i = totpart;
i < newtotpart;
i++, pa++, point++) {
4571 for (k = 0, hkey = pa->
hair; k < pa->totkey; k++, hkey++, key++) {
4594 KDTreeNearest_3d ptn[3];
4596 float maxd, totw = 0.0, weight[3];
4609 maxw = BLI_kdtree_3d_find_nearest_n(
tree, co1, ptn, 3);
4611 maxd = ptn[maxw - 1].dist;
4613 for (
w = 0;
w < maxw;
w++) {
4614 weight[
w] =
float(
pow(2.0,
double(-6.0f * ptn[
w].dist / maxd)));
4617 for (;
w < 3;
w++) {
4622 for (
w = 0;
w < maxw;
w++) {
4627 for (
w = 0;
w < maxw;
w++) {
4628 weight[
w] = 1.0f / maxw;
4635 thkey = pa->
hair + k;
4636 thkey->
time = pa->
time + k * framestep;
4638 key3[0].
time = thkey->
time / 100.0f;
4669 for (k = 0, hkey = pa->
hair; k < pset->totaddkey; k++, hkey++) {
4671 hkey->
time += k * framestep;
4675 for (k = 0, hkey = pa->
hair; k < pset->totaddkey; k++, hkey++) {
4683 BLI_kdtree_3d_free(
tree);
4734 bedit->
scene = scene;
4759 float vec[3], mousef[2];
4761 int flip, mouse[2], removed = 0, added = 0, selected = 0, tot_steps = 1,
step = 1;
4770 mouse[0] = mousef[0];
4771 mouse[1] = mousef[1];
4792 (dx != 0 || dy != 0)) ||
4804 dx /=
float(tot_steps);
4805 dy /=
float(tot_steps);
4813 const float xy_delta[2] = {dx, dy};
4818 if (
data.combfac < 0.0f) {
4819 data.combfac = 1.0f - 9.0f *
data.combfac;
4822 data.combfac = 1.0f -
data.combfac;
4863 if (brush->
invert ^ flip) {
4864 data.growfac = 1.0f -
data.growfac;
4867 data.growfac = 1.0f +
data.growfac;
4882 data.select = selected;
4885 if (
data.pufffac < 0.0f) {
4886 data.pufffac = 1.0f - 9.0f *
data.pufffac;
4889 data.pufffac = 1.0f -
data.pufffac;
4981 pset->
flag |= lock_root;
5041 switch (event->
type) {
5074 ot->name =
"Brush Edit";
5075 ot->idname =
"PARTICLE_OT_brush_edit";
5076 ot->description =
"Apply a stroke of brush to the particles";
5093 ot->srna,
"pen_flip",
false,
"Pen Flip",
"Whether a tablet's eraser mode is being used");
5129 data->bvhdata->raycast_callback(
data->bvhdata, index, ray, hit);
5131 if (hit->
index != -1) {
5140 const float dir[3] = {1.0f, 0.0f, 0.0f};
5153 return (userdata.
num_hits % 2) == 1;
5164 float cut_time = 1.0;
5181 for (k = 0; k < totkeys; k++, key++) {
5184 float co_curr_shape[3], co_next_shape[3];
5191 sub_v3_v3v3(dir_shape, co_next_shape, co_curr_shape);
5194 memset(&hit, 0,
sizeof(hit));
5196 hit.
dist = len_shape;
5202 data->shape_bvh->raycast_callback,
5204 if (hit.
index >= 0) {
5205 if (hit.
dist < len_shape) {
5206 cut_time = ((hit.
dist / len_shape) +
float(k)) /
float(totkeys);
5215 if (cut_time < 0.0f) {
5287 pset->
flag |= lock_root;
5295 ot->name =
"Shape Cut";
5296 ot->idname =
"PARTICLE_OT_shape_cut";
5297 ot->description =
"Cut hair to conform to the set shape object";
5326 if (psmd !=
nullptr) {
5332 if (!(psys && psmd && psmd_eval->
mesh_final) && !cache) {
5344 edit = (psys) ? psys->
edit : cache->
edit;
5359 if (psys && !cache) {
5373 point->totkey = pa->
totkey;
5380 key->time = &hkey->
time;
5398 edit->
psys =
nullptr;
5411 if (!point->totkey) {
5416 key = point->keys + point->totkey;
5422 key->ftime =
float(pm->frame);
5423 key->time = &key->ftime;
5433 if (psys && !cache) {
5461 if (psys->edit !=
nullptr) {
5463 psys->free_edit(psys->edit);
5464 psys->free_edit =
nullptr;
5465 psys->edit =
nullptr;
5490 if (edit && edit->
psys) {
5536 const bool is_mode_set = (ob->
mode & mode_flag) != 0;
5562 ot->name =
"Particle Edit Toggle";
5563 ot->idname =
"PARTICLE_OT_particle_edit_toggle";
5564 ot->description =
"Toggle particle edit mode";
5589 psys->
edit =
nullptr;
5616 ot->name =
"Clear Edited";
5617 ot->idname =
"PARTICLE_OT_edited_clear";
5618 ot->description =
"Undo all edition performed on the particle system";
5648 int num_selected = 0;
5649 float total_length = 0;
5655 if (num_selected == 0) {
5658 return total_length / num_selected;
5663 float orig_prev_co[3], prev_co[3];
5689 if (point_length != 0.0f) {
5690 const float factor =
length / point_length;
5713 if (average_length == 0.0f) {
5733 ot->name =
"Unify Length";
5734 ot->idname =
"PARTICLE_OT_unify_length";
5735 ot->description =
"Make selected hair the same length";
float BKE_brush_weight_get(const Paint *paint, const Brush *brush)
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, blender::float3 &r_min, blender::float3 &r_max)
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
@ BKE_PARTICLE_BATCH_DIRTY_ALL
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)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
void void BLI_INLINE bool BLI_listbase_is_single(const 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 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])
void unit_m4(float m[4][4])
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
ATTR_WARN_UNUSED_RESULT const size_t num
struct RNG * BLI_rng_new(unsigned int seed)
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
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)
Platform independent time functions.
long int BLI_time_now_seconds_i(void)
#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)
#define BLT_I18NCONTEXT_DEFAULT
void DEG_id_tag_update(ID *id, unsigned int flags)
bool DEG_is_active(const Depsgraph *depsgraph)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
#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)
void ED_view3d_win_to_delta(const ARegion *region, const float xy_delta[2], float zfac, float r_out[3], bool precise=false)
@ 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)
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)
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])
void view3d_operator_needs_gpu(const bContext *C)
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_line_smooth(bool enable)
void GPU_blend(GPUBlend blend)
Read Guarded memory(de)allocation.
#define RNA_BEGIN(sptr, itemptr, propname)
BMesh const char void * data
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.
static void mul(btAlignedObjectArray< T > &items, const Q &value)
static unsigned long seed
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
static wmOperatorStatus hide_exec(bContext *C, wmOperator *op)
static wmOperatorStatus reveal_exec(bContext *C, wmOperator *op)
static wmOperatorStatus subdivide_exec(bContext *C, wmOperator *op)
static wmOperatorStatus select_linked_exec(bContext *C, wmOperator *)
static wmOperatorStatus select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static wmOperatorStatus delete_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem delete_type_items[]
static bool is_inside(int x, int y, int cols, int rows)
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
float length(VecOp< float, D >) RET
float distance(VecOp< float, D >, VecOp< float, D >) RET
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
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
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 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])
bool ED_object_particle_edit_mode_supported(const Object *ob)
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)
static wmOperatorStatus particle_edit_toggle_exec(bContext *C, wmOperator *op)
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 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)
static wmOperatorStatus select_random_exec(bContext *C, wmOperator *op)
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)
void ED_object_particle_edit_mode_exit_ex(Scene *scene, Object *ob)
static void brush_add_count_iter_reduce(const void *__restrict, void *__restrict join_v, void *__restrict chunk_v)
static wmOperatorStatus mirror_exec(bContext *C, wmOperator *)
static wmOperatorStatus delete_exec(bContext *C, wmOperator *op)
void PE_current_changed(Depsgraph *depsgraph, Scene *scene, Object *ob)
void(*)(PEData *data, float mat[4][4], float imat[4][4], int point_index, int key_index, PTCacheEditKey *key, float mouse_distance) ForHitKeyMatFunc
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 wmOperatorStatus hide_exec(bContext *C, wmOperator *op)
static void PE_set_view3d_data(bContext *C, PEData *data)
static float calculate_point_length(PTCacheEditPoint *point)
static wmOperatorStatus select_less_exec(bContext *C, wmOperator *)
static void foreach_selected_key(PEData *data, ForKeyFunc func)
void PARTICLE_OT_delete(wmOperatorType *ot)
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 brush_drawcursor(bContext *C, const blender::int2 &xy, const blender::float2 &, void *)
static void select_more_keys(PEData *data, int point_index)
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 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 wmOperatorStatus select_linked_exec(bContext *C, wmOperator *)
static void update_velocities(PTCacheEdit *edit)
void PARTICLE_OT_select_linked(wmOperatorType *ot)
static wmOperatorStatus brush_edit_modal(bContext *C, wmOperator *op, const wmEvent *event)
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)
static wmOperatorStatus shape_cut_exec(bContext *C, wmOperator *)
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 wmOperatorStatus weight_set_exec(bContext *C, wmOperator *op)
void update_world_cos(Object *ob, PTCacheEdit *edit)
static wmOperatorStatus pe_select_all_exec(bContext *C, wmOperator *op)
static wmOperatorStatus clear_edited_exec(bContext *C, wmOperator *)
ParticleEditSettings * PE_settings(Scene *scene)
static void apply_lengths_iter(void *__restrict iter_data_v, const int iter, const TaskParallelTLS *__restrict)
void PARTICLE_OT_select_more(wmOperatorType *ot)
static wmOperatorStatus select_tips_exec(bContext *C, wmOperator *op)
void PARTICLE_OT_rekey(wmOperatorType *ot)
static void rekey_particle(PEData *data, int pa_index)
void(*)(PEData *data, const float mat[4][4], const float imat[4][4], int point_index, int key_index, PTCacheEditKey *key) ForKeyMatFunc
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 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 float pe_brush_size_get(const Scene *, ParticleBrushData *brush)
void PARTICLE_OT_particle_edit_toggle(wmOperatorType *ot)
static wmOperatorStatus select_linked_pick_exec(bContext *C, wmOperator *op)
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 wmOperatorStatus remove_doubles_exec(bContext *C, wmOperator *op)
void PARTICLE_OT_select_tips(wmOperatorType *ot)
static wmOperatorStatus select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void select_less_keys(PEData *data, int point_index)
static bool brush_edit_poll(bContext *C)
bool PE_mouse_particles(bContext *C, const int mval[2], const SelectPick_Params ¶ms)
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 void PE_apply_mirror(Object *ob, ParticleSystem *psys)
static wmOperatorStatus reveal_exec(bContext *C, wmOperator *op)
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)
bool PE_circle_select(bContext *C, wmGenericUserData *wm_userdata, const int sel_op, const int mval[2], float rad)
static void scale_points_to_length(PTCacheEdit *edit, float length)
static void brush_edit_apply_event(bContext *C, wmOperator *op, const wmEvent *event)
static void select_root(PEData *data, int point_index)
static wmOperatorStatus rekey_exec(bContext *C, wmOperator *op)
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 wmOperatorStatus subdivide_exec(bContext *C, wmOperator *)
static void brush_add_count_iter_free(const void *__restrict, void *__restrict chunk_v)
static void brush_cut(PEData *data, int pa_index)
static wmOperatorStatus select_more_exec(bContext *C, wmOperator *)
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 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 wmOperatorStatus brush_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static PTCacheEdit * pe_get_current(Depsgraph *depsgraph, Scene *scene, Object *ob, bool create)
static void iterate_lengths_iter(void *__restrict iter_data_v, const int iter, const TaskParallelTLS *__restrict)
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 wmOperatorStatus brush_edit_exec(bContext *C, wmOperator *op)
static wmOperatorStatus select_roots_exec(bContext *C, wmOperator *op)
static wmOperatorStatus unify_length_exec(bContext *C, wmOperator *)
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
blender::bke::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)
blender::bke::BVHTreeFromMesh * bvhdata
struct ToolSettings * toolsettings
TaskParallelReduceFunc func_reduce
TaskParallelFreeFunc func_free
size_t userdata_chunk_size
wmEventModifierFlag modifier
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)
wmOperatorStatus WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)
bool WM_paint_cursor_end(wmPaintCursor *handle)
wmPaintCursor * WM_paint_cursor_activate(short space_type, short region_type, bool(*poll)(bContext *C), wmPaintCursorDraw draw, void *customdata)
wmOperatorStatus WM_operator_props_popup(bContext *C, wmOperator *op, const wmEvent *)