Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/physics/particle_edit.c
| Show First 20 Lines • Show All 399 Lines • ▼ Show 20 Lines | typedef struct PEData { | ||||
| BVHTreeFromMesh shape_bvh; | BVHTreeFromMesh shape_bvh; | ||||
| Depsgraph *depsgraph; | Depsgraph *depsgraph; | ||||
| RNG *rng; | RNG *rng; | ||||
| const int *mval; | const int *mval; | ||||
| const rcti *rect; | const rcti *rect; | ||||
| float rad; | float rad; | ||||
| float dist; | |||||
| float dval; | float dval; | ||||
| int select; | int select; | ||||
| eSelectOp sel_op; | eSelectOp sel_op; | ||||
| float *dvec; | float *dvec; | ||||
| float combfac; | float combfac; | ||||
| float pufffac; | float pufffac; | ||||
| float cutfac; | float cutfac; | ||||
| ▲ Show 20 Lines • Show All 179 Lines • ▼ Show 20 Lines | LOOP_SELECTED_KEYS { | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| /*************************** iterators *******************************/ | /*************************** iterators *******************************/ | ||||
| typedef void (*ForPointFunc)(PEData *data, int point_index); | typedef void (*ForPointFunc)( | ||||
| typedef void (*ForKeyFunc)(PEData *data, int point_index, int key_index, bool is_inside); | PEData *data, | ||||
| typedef void (*ForKeyMatFunc)(PEData *data, float mat[4][4], float imat[4][4], int point_index, int key_index, PTCacheEditKey *key); | int point_index); | ||||
| typedef void (*ForHitPointFunc)( | |||||
| PEData *data, | |||||
| int point_index, | |||||
| float mouse_distance); | |||||
| typedef void (*ForKeyFunc)( | |||||
| PEData *data, | |||||
| int point_index, | |||||
| int key_index, | |||||
| bool is_inside); | |||||
| typedef void (*ForKeyMatFunc)( | |||||
| PEData *data, | |||||
| float mat[4][4], | |||||
| float imat[4][4], | |||||
| int point_index, | |||||
| int key_index, | |||||
| PTCacheEditKey *key); | |||||
| typedef void (*ForHitKeyMatFunc)( | |||||
| PEData *data, | |||||
| float mat[4][4], | |||||
| float imat[4][4], | |||||
| int point_index, | |||||
| int key_index, | |||||
| PTCacheEditKey *key, | |||||
| float mouse_distance); | |||||
| enum eParticleSelectFlag { | enum eParticleSelectFlag { | ||||
| PSEL_NEAREST = (1 << 0), | PSEL_NEAREST = (1 << 0), | ||||
| PSEL_ALL_KEYS = (1 << 1), | PSEL_ALL_KEYS = (1 << 1), | ||||
| }; | }; | ||||
| static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, const enum eParticleSelectFlag flag) | static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, const enum eParticleSelectFlag flag) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, const enum eParticleSelectFlag flag) | ||||
| /* do nearest only */ | /* do nearest only */ | ||||
| if (flag & PSEL_NEAREST) { | if (flag & PSEL_NEAREST) { | ||||
| if (nearest_point != -1) { | if (nearest_point != -1) { | ||||
| func(data, nearest_point, nearest_key, true); | func(data, nearest_point, nearest_key, true); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void foreach_mouse_hit_point(PEData *data, ForPointFunc func, int selected) | static void foreach_mouse_hit_point(PEData *data, ForHitPointFunc func, int selected) | ||||
| { | { | ||||
| ParticleEditSettings *pset = PE_settings(data->scene); | ParticleEditSettings *pset = PE_settings(data->scene); | ||||
| PTCacheEdit *edit = data->edit; | PTCacheEdit *edit = data->edit; | ||||
| POINT_P; KEY_K; | POINT_P; KEY_K; | ||||
| /* all is selected in path mode */ | /* all is selected in path mode */ | ||||
| if (pset->selectmode == SCE_SELECT_PATH) | if (pset->selectmode == SCE_SELECT_PATH) | ||||
| selected = 0; | selected = 0; | ||||
| LOOP_VISIBLE_POINTS { | LOOP_VISIBLE_POINTS { | ||||
| if (pset->selectmode == SCE_SELECT_END) { | if (pset->selectmode == SCE_SELECT_END) { | ||||
| if (point->totkey) { | if (point->totkey) { | ||||
| /* only do end keys */ | /* only do end keys */ | ||||
| key = point->keys + point->totkey - 1; | key = point->keys + point->totkey - 1; | ||||
| if (selected == 0 || key->flag & PEK_SELECT) | if (selected == 0 || key->flag & PEK_SELECT) { | ||||
| if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) | float mouse_distance; | ||||
| func(data, p); | if (key_inside_circle(data, data->rad, KEY_WCO, &mouse_distance)) { | ||||
| func(data, p, mouse_distance); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* do all keys */ | /* do all keys */ | ||||
| LOOP_VISIBLE_KEYS { | LOOP_VISIBLE_KEYS { | ||||
| if (selected == 0 || key->flag & PEK_SELECT) { | if (selected == 0 || key->flag & PEK_SELECT) { | ||||
| if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) { | float mouse_distance; | ||||
| func(data, p); | if (key_inside_circle(data, data->rad, KEY_WCO, &mouse_distance)) { | ||||
| func(data, p, mouse_distance); | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| typedef struct KeyIterData { | typedef struct KeyIterData { | ||||
| PEData *data; | PEData *data; | ||||
| PTCacheEdit *edit; | PTCacheEdit *edit; | ||||
| int selected; | int selected; | ||||
| ForKeyMatFunc func; | ForHitKeyMatFunc func; | ||||
| } KeyIterData; | } KeyIterData; | ||||
| static void foreach_mouse_hit_key_iter( | static void foreach_mouse_hit_key_iter( | ||||
| void *__restrict iter_data_v, | void *__restrict iter_data_v, | ||||
| const int iter, | const int iter, | ||||
| const ParallelRangeTLS *__restrict UNUSED(tls)) | const ParallelRangeTLS *__restrict UNUSED(tls)) | ||||
| { | { | ||||
| KeyIterData *iter_data = (KeyIterData *)iter_data_v; | KeyIterData *iter_data = (KeyIterData *)iter_data_v; | ||||
| Show All 11 Lines | static void foreach_mouse_hit_key_iter( | ||||
| unit_m4(mat); | unit_m4(mat); | ||||
| unit_m4(imat); | unit_m4(imat); | ||||
| if (pset->selectmode == SCE_SELECT_END) { | if (pset->selectmode == SCE_SELECT_END) { | ||||
| if (point->totkey) { | if (point->totkey) { | ||||
| /* only do end keys */ | /* only do end keys */ | ||||
| PTCacheEditKey *key = point->keys + point->totkey - 1; | PTCacheEditKey *key = point->keys + point->totkey - 1; | ||||
| if (selected == 0 || key->flag & PEK_SELECT) { | if (selected == 0 || key->flag & PEK_SELECT) { | ||||
| if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) { | float mouse_distance; | ||||
| if (key_inside_circle(data, data->rad, KEY_WCO, &mouse_distance)) { | |||||
| if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { | if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { | ||||
| psys_mat_hair_to_global(data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat); | psys_mat_hair_to_global(data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat); | ||||
| invert_m4_m4(imat, mat); | invert_m4_m4(imat, mat); | ||||
| } | } | ||||
| iter_data->func(data, mat, imat, iter, point->totkey - 1, key); | iter_data->func(data, mat, imat, iter, point->totkey - 1, key, mouse_distance); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* do all keys */ | /* do all keys */ | ||||
| PTCacheEditKey *key; | PTCacheEditKey *key; | ||||
| int k; | int k; | ||||
| LOOP_VISIBLE_KEYS { | LOOP_VISIBLE_KEYS { | ||||
| if (selected == 0 || key->flag & PEK_SELECT) { | if (selected == 0 || key->flag & PEK_SELECT) { | ||||
| if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) { | float mouse_distance; | ||||
| if (key_inside_circle(data, data->rad, KEY_WCO, &mouse_distance)) { | |||||
| if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { | if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { | ||||
| psys_mat_hair_to_global(data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat); | psys_mat_hair_to_global(data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat); | ||||
| invert_m4_m4(imat, mat); | invert_m4_m4(imat, mat); | ||||
| } | } | ||||
| iter_data->func(data, mat, imat, iter, k, key); | iter_data->func(data, mat, imat, iter, k, key, mouse_distance); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected) | static void foreach_mouse_hit_key(PEData *data, ForHitKeyMatFunc func, int selected) | ||||
| { | { | ||||
| PTCacheEdit *edit = data->edit; | PTCacheEdit *edit = data->edit; | ||||
| ParticleEditSettings *pset = PE_settings(data->scene); | ParticleEditSettings *pset = PE_settings(data->scene); | ||||
| /* all is selected in path mode */ | /* all is selected in path mode */ | ||||
| if (pset->selectmode == SCE_SELECT_PATH) { | if (pset->selectmode == SCE_SELECT_PATH) { | ||||
| selected = 0; | selected = 0; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 2,422 Lines • ▼ Show 20 Lines | void PARTICLE_OT_mirror(wmOperatorType *ot) | ||||
| ot->poll = PE_hair_poll; | ot->poll = PE_hair_poll; | ||||
| /* flags */ | /* flags */ | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| } | } | ||||
| /************************* brush edit callbacks ********************/ | /************************* brush edit callbacks ********************/ | ||||
| static void brush_comb(PEData *data, float UNUSED(mat[4][4]), float imat[4][4], int point_index, int key_index, PTCacheEditKey *key) | static void brush_comb( | ||||
| PEData *data, | |||||
| float UNUSED(mat[4][4]), | |||||
| float imat[4][4], | |||||
| int point_index, | |||||
| int key_index, | |||||
| PTCacheEditKey *key, | |||||
| float mouse_distance) | |||||
| { | { | ||||
| ParticleEditSettings *pset = PE_settings(data->scene); | ParticleEditSettings *pset = PE_settings(data->scene); | ||||
| float cvec[3], fac; | float cvec[3], fac; | ||||
| if (pset->flag & PE_LOCK_FIRST && key_index == 0) return; | if (pset->flag & PE_LOCK_FIRST && key_index == 0) return; | ||||
| fac = (float)pow((double)(1.0f - data->dist / data->rad), (double)data->combfac); | fac = (float)pow((double)(1.0f - mouse_distance / data->rad), (double)data->combfac); | ||||
| copy_v3_v3(cvec, data->dvec); | copy_v3_v3(cvec, data->dvec); | ||||
| mul_mat3_m4_v3(imat, cvec); | mul_mat3_m4_v3(imat, cvec); | ||||
| mul_v3_fl(cvec, fac); | mul_v3_fl(cvec, fac); | ||||
| add_v3_v3(key->co, cvec); | add_v3_v3(key->co, cvec); | ||||
| (data->edit->points + point_index)->flag |= PEP_EDIT_RECALC; | (data->edit->points + point_index)->flag |= PEP_EDIT_RECALC; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | if (cut) { | ||||
| } | } | ||||
| else { | else { | ||||
| rekey_particle_to_time(data->context, data->scene, ob, pa_index, cut_time); | rekey_particle_to_time(data->context, data->scene, ob, pa_index, cut_time); | ||||
| edit->points[pa_index].flag |= PEP_EDIT_RECALC; | edit->points[pa_index].flag |= PEP_EDIT_RECALC; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void brush_length(PEData *data, int point_index) | static void brush_length(PEData *data, int point_index, float UNUSED(mouse_distance)) | ||||
| { | { | ||||
| PTCacheEdit *edit = data->edit; | PTCacheEdit *edit = data->edit; | ||||
| PTCacheEditPoint *point = edit->points + point_index; | PTCacheEditPoint *point = edit->points + point_index; | ||||
| KEY_K; | KEY_K; | ||||
| float dvec[3], pvec[3] = {0.0f, 0.0f, 0.0f}; | float dvec[3], pvec[3] = {0.0f, 0.0f, 0.0f}; | ||||
| LOOP_KEYS { | LOOP_KEYS { | ||||
| if (k == 0) { | if (k == 0) { | ||||
| copy_v3_v3(pvec, key->co); | copy_v3_v3(pvec, key->co); | ||||
| } | } | ||||
| else { | else { | ||||
| sub_v3_v3v3(dvec, key->co, pvec); | sub_v3_v3v3(dvec, key->co, pvec); | ||||
| copy_v3_v3(pvec, key->co); | copy_v3_v3(pvec, key->co); | ||||
| mul_v3_fl(dvec, data->growfac); | mul_v3_fl(dvec, data->growfac); | ||||
| add_v3_v3v3(key->co, (key - 1)->co, dvec); | add_v3_v3v3(key->co, (key - 1)->co, dvec); | ||||
| } | } | ||||
| } | } | ||||
| point->flag |= PEP_EDIT_RECALC; | point->flag |= PEP_EDIT_RECALC; | ||||
| } | } | ||||
| static void brush_puff(PEData *data, int point_index) | static void brush_puff(PEData *data, int point_index, float mouse_distance) | ||||
| { | { | ||||
| PTCacheEdit *edit = data->edit; | PTCacheEdit *edit = data->edit; | ||||
| ParticleSystem *psys = edit->psys; | ParticleSystem *psys = edit->psys; | ||||
| PTCacheEditPoint *point = edit->points + point_index; | PTCacheEditPoint *point = edit->points + point_index; | ||||
| KEY_K; | KEY_K; | ||||
| float mat[4][4], imat[4][4]; | float mat[4][4], imat[4][4]; | ||||
| float onor_prev[3]; /* previous normal (particle-space) */ | float onor_prev[3]; /* previous normal (particle-space) */ | ||||
| ▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | if (k == 0) { | ||||
| normalize_v3(no_root); | normalize_v3(no_root); | ||||
| if (puff_volume) { | if (puff_volume) { | ||||
| copy_v3_v3(onor_prev, no_root); | copy_v3_v3(onor_prev, no_root); | ||||
| mul_mat3_m4_v3(imat, onor_prev); /* global-space into particle space */ | mul_mat3_m4_v3(imat, onor_prev); /* global-space into particle space */ | ||||
| normalize_v3(onor_prev); | normalize_v3(onor_prev); | ||||
| } | } | ||||
| fac = (float)pow((double)(1.0f - data->dist / data->rad), (double)data->pufffac); | fac = (float)pow((double)(1.0f - mouse_distance / data->rad), (double)data->pufffac); | ||||
| fac *= 0.025f; | fac *= 0.025f; | ||||
| if (data->invert) | if (data->invert) | ||||
| fac = -fac; | fac = -fac; | ||||
| } | } | ||||
| else { | else { | ||||
| /* compute position as if hair was standing up straight. | /* compute position as if hair was standing up straight. | ||||
| * */ | * */ | ||||
| float length; | float length; | ||||
| ▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | #endif | ||||
| } | } | ||||
| } | } | ||||
| if (changed) | if (changed) | ||||
| point->flag |= PEP_EDIT_RECALC; | point->flag |= PEP_EDIT_RECALC; | ||||
| } | } | ||||
| static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[4][4]), float UNUSED(imat[4][4]), int point_index, int key_index, PTCacheEditKey *UNUSED(key)) | static void BKE_brush_weight_get( | ||||
| PEData *data, | |||||
| float UNUSED(mat[4][4]), | |||||
| float UNUSED(imat[4][4]), | |||||
| int point_index, | |||||
| int key_index, | |||||
| PTCacheEditKey *UNUSED(key), | |||||
| float UNUSED(mouse_distance)) | |||||
| { | { | ||||
| /* roots have full weight always */ | /* roots have full weight always */ | ||||
| if (key_index) { | if (key_index) { | ||||
| PTCacheEdit *edit = data->edit; | PTCacheEdit *edit = data->edit; | ||||
| ParticleSystem *psys = edit->psys; | ParticleSystem *psys = edit->psys; | ||||
| ParticleData *pa = psys->particles + point_index; | ParticleData *pa = psys->particles + point_index; | ||||
| pa->hair[key_index].weight = data->weightfac; | pa->hair[key_index].weight = data->weightfac; | ||||
| (data->edit->points + point_index)->flag |= PEP_EDIT_RECALC; | (data->edit->points + point_index)->flag |= PEP_EDIT_RECALC; | ||||
| } | } | ||||
| } | } | ||||
| static void brush_smooth_get(PEData *data, float mat[4][4], float UNUSED(imat[4][4]), int UNUSED(point_index), int key_index, PTCacheEditKey *key) | static void brush_smooth_get( | ||||
| PEData *data, | |||||
| float mat[4][4], | |||||
| float UNUSED(imat[4][4]), | |||||
| int UNUSED(point_index), | |||||
| int key_index, | |||||
| PTCacheEditKey *key, | |||||
| float UNUSED(mouse_distance)) | |||||
| { | { | ||||
| if (key_index) { | if (key_index) { | ||||
| float dvec[3]; | float dvec[3]; | ||||
| sub_v3_v3v3(dvec, key->co, (key - 1)->co); | sub_v3_v3v3(dvec, key->co, (key - 1)->co); | ||||
| mul_mat3_m4_v3(mat, dvec); | mul_mat3_m4_v3(mat, dvec); | ||||
| add_v3_v3(data->vec, dvec); | add_v3_v3(data->vec, dvec); | ||||
| data->tot++; | data->tot++; | ||||
| } | } | ||||
| } | } | ||||
| static void brush_smooth_do(PEData *data, float UNUSED(mat[4][4]), float imat[4][4], int point_index, int key_index, PTCacheEditKey *key) | static void brush_smooth_do( | ||||
| PEData *data, | |||||
| float UNUSED(mat[4][4]), | |||||
| float imat[4][4], | |||||
| int point_index, | |||||
| int key_index, | |||||
| PTCacheEditKey *key, | |||||
| float UNUSED(mouse_distance)) | |||||
| { | { | ||||
| float vec[3], dvec[3]; | float vec[3], dvec[3]; | ||||
| if (key_index) { | if (key_index) { | ||||
| copy_v3_v3(vec, data->vec); | copy_v3_v3(vec, data->vec); | ||||
| mul_mat3_m4_v3(imat, vec); | mul_mat3_m4_v3(imat, vec); | ||||
| sub_v3_v3v3(dvec, key->co, (key - 1)->co); | sub_v3_v3v3(dvec, key->co, (key - 1)->co); | ||||
| ▲ Show 20 Lines • Show All 1,507 Lines • Show Last 20 Lines | |||||