Particle edit: Initial support of edit with copy-on-write
The idea is that edit mode structure is owned by original object, and used for drawing. This is a bit confusing, especially since path cache is also in that structure and needs evaluated object to calculate cache. In the future we should split edit data from visualization data, but that's bigger refactor.
This commit is contained in:
@@ -2575,6 +2575,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
|
||||
}
|
||||
void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCacheEdit *edit, float cfra, const bool use_render_params)
|
||||
{
|
||||
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
|
||||
ParticleCacheKey *ca, **cache = edit->pathcache;
|
||||
ParticleEditSettings *pset = &scene->toolsettings->particle;
|
||||
|
||||
@@ -2582,8 +2583,19 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
|
||||
PTCacheEditKey *ekey = NULL;
|
||||
|
||||
ParticleSystem *psys = edit->psys;
|
||||
ParticleSystem *psys_eval = NULL;
|
||||
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
|
||||
ParticleData *pa = psys ? psys->particles : NULL;
|
||||
ParticleSystemModifierData *psmd_eval = NULL;
|
||||
|
||||
BLI_assert((ob->id.tag & LIB_TAG_COPY_ON_WRITE) == 0);
|
||||
BLI_assert(psmd != NULL);
|
||||
|
||||
if (psmd != NULL) {
|
||||
psmd_eval = (ParticleSystemModifierData *)modifiers_findByName(ob_eval, psmd->modifier.name);
|
||||
psys_eval = psmd_eval->psys;
|
||||
}
|
||||
|
||||
ParticleData *pa = psys_eval ? psys_eval->particles : NULL;
|
||||
|
||||
ParticleInterpolationData pind;
|
||||
ParticleKey result;
|
||||
@@ -2612,7 +2624,7 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
|
||||
|
||||
/* frs_sec = (psys || edit->pid.flag & PTCACHE_VEL_PER_SEC) ? 25.0f : 1.0f; */ /* UNUSED */
|
||||
|
||||
const bool use_weight = (pset->brushtype == PE_BRUSH_WEIGHT) && (psys != NULL) && (psys->particles != NULL);
|
||||
const bool use_weight = (pset->brushtype == PE_BRUSH_WEIGHT) && (psys_eval != NULL) && (psys_eval->particles != NULL);
|
||||
|
||||
if (use_weight) {
|
||||
; /* use weight painting colors now... */
|
||||
@@ -2657,10 +2669,10 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
|
||||
cache[i]->segments = segments;
|
||||
|
||||
/*--get the first data points--*/
|
||||
init_particle_interpolation(ob, psys, pa, &pind);
|
||||
init_particle_interpolation(ob_eval, psys_eval, pa, &pind);
|
||||
|
||||
if (psys) {
|
||||
psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat);
|
||||
if (psys_eval) {
|
||||
psys_mat_hair_to_global(ob_eval, psmd_eval->dm_final, psys->part->from, pa, hairmat);
|
||||
copy_v3_v3(rotmat[0], hairmat[2]);
|
||||
copy_v3_v3(rotmat[1], hairmat[1]);
|
||||
copy_v3_v3(rotmat[2], hairmat[0]);
|
||||
@@ -2679,7 +2691,7 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
|
||||
time = (float)k / (float)segments;
|
||||
t = birthtime + time * (dietime - birthtime);
|
||||
result.time = -t;
|
||||
do_particle_interpolation(psys, i, pa, t, &pind, &result);
|
||||
do_particle_interpolation(psys_eval, i, pa, t, &pind, &result);
|
||||
copy_v3_v3(ca->co, result.co);
|
||||
|
||||
/* non-hair points are already in global space */
|
||||
|
||||
@@ -2886,19 +2886,19 @@ Gwn_Batch *DRW_cache_particles_get_dots(Object *object, ParticleSystem *psys)
|
||||
return DRW_particles_batch_cache_get_dots(object, psys);
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_cache_particles_get_edit_strands(struct PTCacheEdit *edit)
|
||||
Gwn_Batch *DRW_cache_particles_get_edit_strands(Object *object, struct PTCacheEdit *edit)
|
||||
{
|
||||
return DRW_particles_batch_cache_get_edit_strands(edit);
|
||||
return DRW_particles_batch_cache_get_edit_strands(object, edit);
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_cache_particles_get_edit_inner_points(struct PTCacheEdit *edit)
|
||||
Gwn_Batch *DRW_cache_particles_get_edit_inner_points(Object *object, struct PTCacheEdit *edit)
|
||||
{
|
||||
return DRW_particles_batch_cache_get_edit_inner_points(edit);
|
||||
return DRW_particles_batch_cache_get_edit_inner_points(object, edit);
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_cache_particles_get_edit_tip_points(struct PTCacheEdit *edit)
|
||||
Gwn_Batch *DRW_cache_particles_get_edit_tip_points(Object *object, struct PTCacheEdit *edit)
|
||||
{
|
||||
return DRW_particles_batch_cache_get_edit_tip_points(edit);
|
||||
return DRW_particles_batch_cache_get_edit_tip_points(object, edit);
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_cache_particles_get_prim(int type)
|
||||
|
||||
@@ -169,9 +169,9 @@ struct Gwn_Batch *DRW_cache_lattice_vert_overlay_get(struct Object *ob);
|
||||
/* Particles */
|
||||
struct Gwn_Batch *DRW_cache_particles_get_hair(struct ParticleSystem *psys, struct ModifierData *md);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_dots(struct Object *object, struct ParticleSystem *psys);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_edit_strands(struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_edit_inner_points(struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_edit_tip_points(struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_edit_strands(struct Object *object, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_edit_inner_points(struct Object *object, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_edit_tip_points(struct Object *object, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_prim(int type);
|
||||
|
||||
/* Metaball */
|
||||
|
||||
@@ -125,8 +125,8 @@ void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me);
|
||||
/* Particles */
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_hair(struct ParticleSystem *psys, struct ModifierData *md);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_dots(struct Object *object, struct ParticleSystem *psys);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(struct Object *object, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(struct Object *object, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(struct Object *object, struct PTCacheEdit *edit);
|
||||
|
||||
#endif /* __DRAW_CACHE_IMPL_H__ */
|
||||
|
||||
@@ -597,10 +597,25 @@ Gwn_Batch *DRW_particles_batch_cache_get_dots(Object *object, ParticleSystem *ps
|
||||
return cache->hairs;
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(PTCacheEdit *edit)
|
||||
/* TODO(sergey): Avoid linear lookup. */
|
||||
static ParticleBatchCache *particle_batch_cache_get_edit(Object *object, PTCacheEdit *edit)
|
||||
{
|
||||
ParticleSystem *psys_orig = edit->psys;
|
||||
for (ParticleSystem *psys_eval = object->particlesystem.first;
|
||||
psys_eval != NULL;
|
||||
psys_eval = psys_eval->next)
|
||||
{
|
||||
if (STREQ(psys_orig->name, psys_eval->name)) {
|
||||
return particle_batch_cache_get(psys_eval);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(Object *object, PTCacheEdit *edit)
|
||||
{
|
||||
ParticleSystem *psys = edit->psys;
|
||||
ParticleBatchCache *cache = particle_batch_cache_get(psys);
|
||||
ParticleBatchCache *cache = particle_batch_cache_get_edit(object, edit);
|
||||
if (cache->hairs != NULL) {
|
||||
return cache->hairs;
|
||||
}
|
||||
@@ -676,10 +691,9 @@ static void particle_batch_cache_ensure_edit_inner_pos(
|
||||
}
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(PTCacheEdit *edit)
|
||||
Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(Object *object, PTCacheEdit *edit)
|
||||
{
|
||||
ParticleSystem *psys = edit->psys;
|
||||
ParticleBatchCache *cache = particle_batch_cache_get(psys);
|
||||
ParticleBatchCache *cache = particle_batch_cache_get_edit(object, edit);
|
||||
if (cache->edit_inner_points != NULL) {
|
||||
return cache->edit_inner_points;
|
||||
}
|
||||
@@ -692,7 +706,7 @@ Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(PTCacheEdit *edit)
|
||||
}
|
||||
|
||||
static void ensure_edit_tip_points_count(const PTCacheEdit *edit,
|
||||
ParticleBatchCache *cache)
|
||||
ParticleBatchCache *cache)
|
||||
{
|
||||
if (cache->edit_tip_pos != NULL) {
|
||||
return;
|
||||
@@ -738,10 +752,9 @@ static void particle_batch_cache_ensure_edit_tip_pos(
|
||||
}
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(PTCacheEdit *edit)
|
||||
Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(Object *object, PTCacheEdit *edit)
|
||||
{
|
||||
ParticleSystem *psys = edit->psys;
|
||||
ParticleBatchCache *cache = particle_batch_cache_get(psys);
|
||||
ParticleBatchCache *cache = particle_batch_cache_get_edit(object, edit);
|
||||
if (cache->edit_tip_points != NULL) {
|
||||
return cache->edit_tip_points;
|
||||
}
|
||||
|
||||
@@ -139,18 +139,30 @@ static void particle_cache_init(void *vedata)
|
||||
DRW_shgroup_uniform_float(stl->g_data->tip_points_group, "outlineWidth", &outline_width, 1);
|
||||
}
|
||||
|
||||
static void draw_update_ptcache_edit(Object *object, PTCacheEdit *edit)
|
||||
/* TODO(sergey): Avoid linear lookup. */
|
||||
static void draw_update_ptcache_edit(Object *object_eval, PTCacheEdit *edit)
|
||||
{
|
||||
if (edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) {
|
||||
if (edit->psys == NULL) {
|
||||
return;
|
||||
}
|
||||
ParticleSystem *psys_eval;
|
||||
for (psys_eval = object_eval->particlesystem.first;
|
||||
psys_eval != NULL;
|
||||
psys_eval = psys_eval->next)
|
||||
{
|
||||
if (STREQ(edit->psys->name, psys_eval->name)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (psys_eval->flag & PSYS_HAIR_UPDATED) {
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Scene *scene_orig = (Scene *)DEG_get_original_id(&draw_ctx->scene->id);
|
||||
Object *object_orig = DEG_get_original_object(object);
|
||||
Object *object_orig = DEG_get_original_object(object_eval);
|
||||
PE_update_object(draw_ctx->depsgraph, scene_orig, object_orig, 0);
|
||||
}
|
||||
BLI_assert(edit->pathcache != NULL);
|
||||
}
|
||||
|
||||
|
||||
static void particle_edit_cache_populate(void *vedata,
|
||||
Object *object,
|
||||
PTCacheEdit *edit)
|
||||
@@ -160,35 +172,32 @@ static void particle_edit_cache_populate(void *vedata,
|
||||
draw_update_ptcache_edit(object, edit);
|
||||
ParticleEditSettings *pset = PE_settings(draw_ctx->scene);
|
||||
{
|
||||
struct Gwn_Batch *strands = DRW_cache_particles_get_edit_strands(edit);
|
||||
struct Gwn_Batch *strands =
|
||||
DRW_cache_particles_get_edit_strands(object, edit);
|
||||
DRW_shgroup_call_add(stl->g_data->strands_group, strands, NULL);
|
||||
}
|
||||
if (pset->selectmode == SCE_SELECT_POINT) {
|
||||
struct Gwn_Batch *points = DRW_cache_particles_get_edit_inner_points(edit);
|
||||
struct Gwn_Batch *points =
|
||||
DRW_cache_particles_get_edit_inner_points(object, edit);
|
||||
DRW_shgroup_call_add(stl->g_data->inner_points_group, points, NULL);
|
||||
}
|
||||
if (ELEM(pset->selectmode, SCE_SELECT_POINT, SCE_SELECT_END)) {
|
||||
struct Gwn_Batch *points = DRW_cache_particles_get_edit_tip_points(edit);
|
||||
struct Gwn_Batch *points =
|
||||
DRW_cache_particles_get_edit_tip_points(object, edit);
|
||||
DRW_shgroup_call_add(stl->g_data->tip_points_group, points, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void particle_cache_populate(void *vedata, Object *object)
|
||||
{
|
||||
for (ParticleSystem *psys = object->particlesystem.first;
|
||||
psys != NULL;
|
||||
psys = psys->next)
|
||||
{
|
||||
if (!psys_check_enabled(object, psys, false)) {
|
||||
continue;
|
||||
}
|
||||
PTCacheEdit *edit = PE_get_current_from_psys(psys);
|
||||
if (edit == NULL) {
|
||||
continue;
|
||||
}
|
||||
particle_edit_cache_populate(vedata, object, edit);
|
||||
break;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Object *object_orig = DEG_get_original_object(object);
|
||||
PTCacheEdit *edit = PE_get_current(draw_ctx->scene, object_orig);
|
||||
if (edit == NULL) {
|
||||
printf("Particle edit struct is NULL, not supposed to happen.\n");
|
||||
return;
|
||||
}
|
||||
particle_edit_cache_populate(vedata, object, edit);
|
||||
}
|
||||
|
||||
/* Optional: Post-cache_populate callback */
|
||||
|
||||
@@ -85,6 +85,8 @@
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "physics_intern.h"
|
||||
|
||||
#include "particle_edit_utildefines.h"
|
||||
@@ -1185,19 +1187,27 @@ static void PE_update_selection(Depsgraph *depsgraph, Scene *scene, Object *ob,
|
||||
DEG_id_tag_update(&ob->id, DEG_TAG_SELECT_UPDATE);
|
||||
}
|
||||
|
||||
void update_world_cos(Object *ob, PTCacheEdit *edit)
|
||||
void update_world_cos(Depsgraph *depsgraph, Object *ob, PTCacheEdit *edit)
|
||||
{
|
||||
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
|
||||
ParticleSystem *psys = edit->psys;
|
||||
ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
|
||||
ParticleSystem *psys_eval = NULL;
|
||||
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
|
||||
ParticleSystemModifierData *psmd_eval = NULL;
|
||||
POINT_P; KEY_K;
|
||||
float hairmat[4][4];
|
||||
|
||||
if (psys==0 || psys->edit==0 || psmd->dm_final==NULL)
|
||||
if (psmd != NULL) {
|
||||
psmd_eval = (ParticleSystemModifierData *)modifiers_findByName(ob_eval, psmd->modifier.name);
|
||||
psys_eval = psmd_eval->psys;
|
||||
}
|
||||
|
||||
if (psys == 0 || psys->edit == 0 || psmd_eval->dm_final == NULL)
|
||||
return;
|
||||
|
||||
LOOP_POINTS {
|
||||
if (!(psys->flag & PSYS_GLOBAL_HAIR))
|
||||
psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles+p, hairmat);
|
||||
psys_mat_hair_to_global(ob_eval, psmd_eval->dm_final, psys->part->from, psys_eval->particles+p, hairmat);
|
||||
|
||||
LOOP_KEYS {
|
||||
copy_v3_v3(key->world_co, key->co);
|
||||
@@ -1287,7 +1297,7 @@ void PE_update_object(Depsgraph *depsgraph, Scene *scene, Object *ob, int usefla
|
||||
if (pe_x_mirror(ob))
|
||||
PE_apply_mirror(ob, edit->psys);
|
||||
if (edit->psys)
|
||||
update_world_cos(ob, edit);
|
||||
update_world_cos(depsgraph, ob, edit);
|
||||
if (pset->flag & PE_AUTO_VELOCITY)
|
||||
update_velocities(edit);
|
||||
PE_hide_keys_time(scene, edit, CFRA);
|
||||
@@ -2970,7 +2980,7 @@ static int mirror_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
|
||||
PE_mirror_x(scene, ob, 0);
|
||||
|
||||
update_world_cos(ob, edit);
|
||||
update_world_cos(CTX_data_depsgraph(C), ob, edit);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
|
||||
@@ -3788,6 +3798,7 @@ static int brush_edit_init(bContext *C, wmOperator *op)
|
||||
static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
|
||||
{
|
||||
BrushEdit *bedit= op->customdata;
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
||||
Scene *scene= bedit->scene;
|
||||
Object *ob= bedit->ob;
|
||||
PTCacheEdit *edit= bedit->edit;
|
||||
@@ -3804,8 +3815,6 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
|
||||
if (!PE_start_edit(edit))
|
||||
return;
|
||||
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
||||
|
||||
RNA_float_get_array(itemptr, "mouse", mousef);
|
||||
mouse[0] = mousef[0];
|
||||
mouse[1] = mousef[1];
|
||||
@@ -3984,7 +3993,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
|
||||
if (pset->brushtype == PE_BRUSH_ADD && pe_x_mirror(ob))
|
||||
PE_mirror_x(scene, ob, 1);
|
||||
|
||||
update_world_cos(ob, edit);
|
||||
update_world_cos(depsgraph, ob, edit);
|
||||
psys_free_path_cache(NULL, edit);
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
@@ -4213,6 +4222,7 @@ static void shape_cut(PEData *data, int pa_index)
|
||||
|
||||
static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
ParticleEditSettings *pset = PE_settings(scene);
|
||||
@@ -4247,7 +4257,7 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
recalc_lengths(edit);
|
||||
|
||||
if (removed) {
|
||||
update_world_cos(ob, edit);
|
||||
update_world_cos(depsgraph, ob, edit);
|
||||
psys_free_path_cache(NULL, edit);
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
@@ -4332,14 +4342,20 @@ void PE_create_particle_edit(
|
||||
Depsgraph *depsgraph, Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys)
|
||||
{
|
||||
PTCacheEdit *edit;
|
||||
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
|
||||
ParticleSystemModifierData *psmd = (psys) ? psys_get_modifier(ob, psys) : NULL;
|
||||
ParticleSystemModifierData *psmd_eval = NULL;
|
||||
POINT_P; KEY_K;
|
||||
ParticleData *pa = NULL;
|
||||
HairKey *hkey;
|
||||
int totpoint;
|
||||
|
||||
if (psmd != NULL) {
|
||||
psmd_eval = (ParticleSystemModifierData *)modifiers_findByName(ob_eval, psmd->modifier.name);
|
||||
}
|
||||
|
||||
/* no psmd->dm happens in case particle system modifier is not enabled */
|
||||
if (!(psys && psmd && psmd->dm_final) && !cache)
|
||||
if (!(psys && psmd_eval && psmd_eval->dm_final) && !cache)
|
||||
return;
|
||||
|
||||
if (cache && cache->flag & PTCACHE_DISK_CACHE)
|
||||
@@ -4386,7 +4402,7 @@ void PE_create_particle_edit(
|
||||
}
|
||||
pa++;
|
||||
}
|
||||
update_world_cos(ob, edit);
|
||||
update_world_cos(depsgraph, ob, edit);
|
||||
}
|
||||
else {
|
||||
PTCacheMem *pm;
|
||||
|
||||
@@ -946,7 +946,7 @@ static void copy_particle_edit(
|
||||
|
||||
pa++;
|
||||
}
|
||||
update_world_cos(ob, edit);
|
||||
update_world_cos(depsgraph, ob, edit);
|
||||
|
||||
UI_GetThemeColor3ubv(TH_EDGE_SELECT, edit->sel_col);
|
||||
UI_GetThemeColor3ubv(TH_WIRE, edit->nosel_col);
|
||||
|
||||
@@ -75,7 +75,7 @@ void PE_create_particle_edit(
|
||||
struct Object *ob, struct PointCache *cache, struct ParticleSystem *psys);
|
||||
void recalc_lengths(struct PTCacheEdit *edit);
|
||||
void recalc_emitter_field(struct Object *ob, struct ParticleSystem *psys);
|
||||
void update_world_cos(struct Object *ob, struct PTCacheEdit *edit);
|
||||
void update_world_cos(struct Depsgraph *depsgraph, struct Object *ob, struct PTCacheEdit *edit);
|
||||
|
||||
/* particle_object.c */
|
||||
void OBJECT_OT_particle_system_add(struct wmOperatorType *ot);
|
||||
|
||||
Reference in New Issue
Block a user