Python API: remove preview/render resolution settings from API functions.

For correct results these must have been set already when the depsgraph was
created and evaluated, so all dependencies have appropriate resolutions too.

For particle we no longer backup and restore the viewport particles to avoid
overwriting them during render, as copy-on-write solves this for us. Even
without COW particles seem to work ok.

This also removes the particle simplification options based on camera. This
was never used much and only available in Blender Internal.

Differential Revision: https://developer.blender.org/D3148
This commit is contained in:
Brecht Van Lommel 2018-04-08 09:28:52 +02:00
parent a1e2415ed5
commit 7b9fb32591
29 changed files with 128 additions and 924 deletions

View File

@ -326,18 +326,6 @@ static bool ObtainCacheParticleVcol(Mesh *mesh,
return true;
}
static void set_resolution(BL::Object& b_ob, BL::Scene& scene, BL::ViewLayer& view_layer, bool render)
{
BL::Object::modifiers_iterator b_mod;
for(b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && ((b_mod->show_viewport()) || (b_mod->show_render()))) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
b_psys.set_resolution(scene, view_layer, b_ob, (render)? 2: 1);
}
}
}
static void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData,
float3 RotCam, bool is_ortho)
{
@ -884,8 +872,7 @@ void BlenderSync::sync_curve_settings()
curve_system_manager->tag_update(scene);
}
void BlenderSync::sync_curves(BL::Depsgraph& b_depsgraph,
Mesh *mesh,
void BlenderSync::sync_curves(Mesh *mesh,
BL::Mesh& b_mesh,
BL::Object& b_ob,
bool motion,
@ -920,10 +907,6 @@ void BlenderSync::sync_curves(BL::Depsgraph& b_depsgraph,
ParticleCurveData CData;
BL::ViewLayer b_view_layer = b_depsgraph.view_layer();
if(!preview)
set_resolution(b_ob, b_scene, b_view_layer, true);
ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview);
/* add hair geometry to mesh */
@ -1066,9 +1049,6 @@ void BlenderSync::sync_curves(BL::Depsgraph& b_depsgraph,
}
}
if(!preview)
set_resolution(b_ob, b_scene, b_view_layer, false);
mesh->compute_bounds();
}

View File

@ -1188,10 +1188,8 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
BL::Mesh b_mesh = object_to_mesh(b_data,
b_ob,
b_scene,
b_depsgraph.view_layer(),
b_depsgraph,
true,
!preview,
need_undeformed,
mesh->subdivision_type);
@ -1207,7 +1205,7 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
}
if(view_layer.use_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
sync_curves(b_depsgraph, mesh, b_mesh, b_ob, false);
sync_curves(mesh, b_mesh, b_ob, false);
if(can_free_caches) {
b_ob.cache_release();
@ -1278,10 +1276,8 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph& b_depsgraph,
/* get derived mesh */
b_mesh = object_to_mesh(b_data,
b_ob,
b_scene,
b_depsgraph.view_layer(),
b_depsgraph,
true,
!preview,
false,
Mesh::SUBDIVISION_NONE);
}
@ -1390,7 +1386,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph& b_depsgraph,
/* hair motion */
if(numkeys)
sync_curves(b_depsgraph, mesh, b_mesh, b_ob, true, motion_step);
sync_curves(mesh, b_mesh, b_ob, true, motion_step);
/* free derived mesh */
b_data.meshes.remove(b_mesh, false, true, false);

View File

@ -236,7 +236,6 @@ static ShaderNode *add_node(Scene *scene,
BL::BlendData& b_data,
BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene,
const bool background,
ShaderGraph *graph,
BL::ShaderNodeTree& b_ntree,
BL::ShaderNode& b_node)
@ -843,12 +842,9 @@ static ShaderNode *add_node(Scene *scene,
point_density->interpolation = get_image_interpolation(b_point_density_node);
point_density->builtin_data = b_point_density_node.ptr.data;
/* 1 - render settings, 0 - vewport settings. */
int settings = background ? 1 : 0;
/* TODO(sergey): Use more proper update flag. */
if(true) {
b_point_density_node.cache_point_density(b_depsgraph, settings);
b_point_density_node.cache_point_density(b_depsgraph);
scene->image_manager->tag_reload_image(
point_density->filename.string(),
point_density->builtin_data,
@ -868,7 +864,6 @@ static ShaderNode *add_node(Scene *scene,
float3 loc, size;
point_density_texture_space(b_depsgraph,
b_point_density_node,
settings,
loc,
size);
point_density->tfm =
@ -1008,7 +1003,6 @@ static void add_nodes(Scene *scene,
BL::BlendData& b_data,
BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene,
const bool background,
ShaderGraph *graph,
BL::ShaderNodeTree& b_ntree,
const ProxyMap &proxy_input_map,
@ -1095,7 +1089,6 @@ static void add_nodes(Scene *scene,
b_data,
b_depsgraph,
b_scene,
background,
graph,
b_group_ntree,
group_proxy_input_map,
@ -1143,7 +1136,6 @@ static void add_nodes(Scene *scene,
b_data,
b_depsgraph,
b_scene,
background,
graph,
b_ntree,
b_shader_node);
@ -1207,7 +1199,6 @@ static void add_nodes(Scene *scene,
BL::BlendData& b_data,
BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene,
const bool background,
ShaderGraph *graph,
BL::ShaderNodeTree& b_ntree)
{
@ -1217,7 +1208,6 @@ static void add_nodes(Scene *scene,
b_data,
b_depsgraph,
b_scene,
background,
graph,
b_ntree,
empty_proxy_map,
@ -1255,7 +1245,7 @@ void BlenderSync::sync_materials(BL::Depsgraph& b_depsgraph, bool update_all)
if(b_mat->use_nodes() && b_mat->node_tree()) {
BL::ShaderNodeTree b_ntree(b_mat->node_tree());
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, !preview, graph, b_ntree);
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
}
else {
DiffuseBsdfNode *diffuse = new DiffuseBsdfNode();
@ -1326,7 +1316,7 @@ void BlenderSync::sync_world(BL::Depsgraph& b_depsgraph, bool update_all)
if(b_world && b_world.use_nodes() && b_world.node_tree()) {
BL::ShaderNodeTree b_ntree(b_world.node_tree());
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, !preview, graph, b_ntree);
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
/* volume */
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
@ -1428,7 +1418,7 @@ void BlenderSync::sync_lamps(BL::Depsgraph& b_depsgraph, bool update_all)
BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, !preview, graph, b_ntree);
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
}
else {
float strength = 1.0f;

View File

@ -120,8 +120,7 @@ private:
BL::Object& b_ob_instance,
bool object_updated,
bool hide_tris);
void sync_curves(BL::Depsgraph& b_depsgraph,
Mesh *mesh,
void sync_curves(Mesh *mesh,
BL::Mesh& b_mesh,
BL::Object& b_ob,
bool motion,

View File

@ -36,7 +36,6 @@ void density_texture_space_invert(float3& loc,
void point_density_texture_space(BL::Depsgraph& b_depsgraph,
BL::ShaderNodeTexPointDensity& b_point_density_node,
int settings,
float3& loc,
float3& size)
{
@ -48,7 +47,6 @@ void point_density_texture_space(BL::Depsgraph& b_depsgraph,
}
float3 min, max;
b_point_density_node.calc_point_density_minmax(b_depsgraph,
settings,
&min[0],
&max[0]);
loc = (min + max) * 0.5f;

View File

@ -24,7 +24,6 @@ CCL_NAMESPACE_BEGIN
void point_density_texture_space(BL::Depsgraph& b_depsgraph,
BL::ShaderNodeTexPointDensity& b_point_density_node,
const int settings,
float3& loc,
float3& size);

View File

@ -45,10 +45,8 @@ void python_thread_state_restore(void **python_thread_state);
static inline BL::Mesh object_to_mesh(BL::BlendData& data,
BL::Object& object,
BL::Scene& scene,
BL::ViewLayer view_layer,
BL::Depsgraph& depsgraph,
bool apply_modifiers,
bool render,
bool calc_undeformed,
Mesh::SubdivisionType subdivision_type)
{
@ -65,7 +63,7 @@ static inline BL::Mesh object_to_mesh(BL::BlendData& data,
subsurf_mod.show_viewport(false);
}
BL::Mesh me = data.meshes.new_from_object(scene, view_layer, object, apply_modifiers, (render)? 2: 1, false, calc_undeformed);
BL::Mesh me = data.meshes.new_from_object(depsgraph, object, apply_modifiers, false, calc_undeformed);
if(subdivision_type != Mesh::SUBDIVISION_NONE) {
BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];

View File

@ -965,22 +965,6 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
col.prop(part, "path_end", text="End", slider=not part.use_absolute_path_time)
col.prop(part, "length_random", text="Random", slider=True)
row = layout.row()
col = row.column()
if part.type == 'HAIR' and part.use_strand_primitive is True and part.child_type == 'INTERPOLATED':
layout.prop(part, "use_simplify")
if part.use_simplify is True:
row = layout.row()
row.prop(part, "simplify_refsize")
row.prop(part, "simplify_rate")
row.prop(part, "simplify_transition")
row = layout.row()
row.prop(part, "use_simplify_viewport")
sub = row.row()
sub.active = part.use_simplify_viewport is True
sub.prop(part, "simplify_viewport")
elif part.render_type == 'OBJECT':
col.prop(part, "dupli_object")
sub = col.row()

View File

@ -141,7 +141,7 @@ float (*BKE_mesh_vertexCos_get(const struct Mesh *me, int *r_numVerts))[3];
void BKE_mesh_split_faces(struct Mesh *mesh, bool free_loop_normals);
struct Mesh *BKE_mesh_new_from_object(const struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, struct Object *ob,
int apply_modifiers, int settings, int calc_tessface, int calc_undeformed);
int apply_modifiers, int calc_tessface, int calc_undeformed);
/* vertex level transformations & checks (no derived mesh) */

View File

@ -49,6 +49,7 @@ struct ParticleSettings;
struct Main;
struct Object;
struct Scene;
struct Depsgraph;
struct DerivedMesh;
struct ModifierData;
struct MTFace;
@ -147,7 +148,7 @@ typedef struct ParticleThreadContext {
float *jit, *jitoff, *weight;
float maxweight;
int *index, *skip, jitlevel;
int *index, jitlevel;
int cfrom, distr;
@ -289,8 +290,8 @@ BLI_INLINE void psys_frand_vec(ParticleSystem *psys, unsigned int seed, float ve
int count_particles(struct ParticleSystem *psys);
int count_particles_mod(struct ParticleSystem *psys, int totgr, int cur);
int psys_get_child_number(struct Scene *scene, struct ParticleSystem *psys);
int psys_get_tot_child(struct Scene *scene, struct ParticleSystem *psys);
int psys_get_child_number(struct Scene *scene, struct ParticleSystem *psys, const bool use_render_params);
int psys_get_tot_child(struct Scene *scene, struct ParticleSystem *psys, const bool use_render_params);
struct ParticleSystem *psys_get_current(struct Object *ob);
/* for rna */
@ -301,7 +302,7 @@ void psys_set_current_num(Object *ob, int index);
struct LatticeDeformData *psys_create_lattice_deform_data(struct ParticleSimulationData *sim);
bool psys_in_edit_mode(struct ViewLayer *view_layer, struct ParticleSystem *psys);
bool psys_in_edit_mode(struct Depsgraph *depsgraph, struct ParticleSystem *psys);
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, const bool use_render_params);
bool psys_check_edited(struct ParticleSystem *psys);
@ -313,8 +314,6 @@ void BKE_particlesettings_free(struct ParticleSettings *part);
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit);
void psys_free(struct Object *ob, struct ParticleSystem *psys);
void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset);
void psys_render_restore(struct Object *ob, struct ParticleSystem *psys);
bool psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params);
void psys_interpolate_uvs(const struct MTFace *tface, int quad, const float w[4], float uvco[2]);
@ -441,34 +440,7 @@ int psys_particle_dm_face_lookup(struct DerivedMesh *dm_final, struct DerivedMes
void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra);
float psys_get_current_display_percentage(struct ParticleSystem *psys);
typedef struct ParticleRenderElem {
int curchild, totchild, reduce;
float lambda, t, scalemin, scalemax;
} ParticleRenderElem;
typedef struct ParticleRenderData {
ChildParticle *child;
ParticleCacheKey **pathcache;
ParticleCacheKey **childcache;
ListBase pathcachebufs, childcachebufs;
int totchild, totcached, totchildcache;
struct DerivedMesh *dm;
int totdmvert, totdmedge, totdmface;
float mat[4][4];
float viewmat[4][4], winmat[4][4];
int winx, winy;
int do_simplify;
int timeoffset;
ParticleRenderElem *elems;
/* ORIGINDEX */
const int *index_mf_to_mpoly;
const int *index_mp_to_orig;
} ParticleRenderData;
float psys_get_current_display_percentage(struct ParticleSystem *psys, const bool use_render_params);
/* psys_reset */
#define PSYS_RESET_ALL 1

View File

@ -66,6 +66,7 @@
#include "BKE_editmesh.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
/* Define for cases when you want extra validation of mesh
* after certain modifications.
@ -2428,12 +2429,12 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
/* settings: 1 - preview, 2 - render */
Mesh *BKE_mesh_new_from_object(
const EvaluationContext *eval_ctx, Main *bmain, Scene *sce, Object *ob,
int apply_modifiers, int settings, int calc_tessface, int calc_undeformed)
int apply_modifiers, int calc_tessface, int calc_undeformed)
{
Mesh *tmpmesh;
Curve *tmpcu = NULL, *copycu;
int i;
const bool render = (settings == eModifierMode_Render);
const bool render = (DEG_get_mode(eval_ctx->depsgraph) == DAG_EVAL_RENDER);
const bool cage = !apply_modifiers;
bool do_mat_id_data_us = true;

View File

@ -1038,7 +1038,6 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys, const int f
BLI_listbase_clear(&psysn->pathcachebufs);
BLI_listbase_clear(&psysn->childcachebufs);
psysn->renderdata = NULL;
/* XXX Never copy caches here? */
psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, flag & ~LIB_ID_COPY_CACHES);

View File

@ -881,7 +881,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
BLI_srandom((unsigned int)(31415926 + psys->seed));
if ((psys->renderdata || part->draw_as == PART_DRAW_REND) && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
if ((for_render || part->draw_as == PART_DRAW_REND) && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
ParticleSimulationData sim = {NULL};
sim.eval_ctx = ctx->eval_ctx;
sim.scene = scene;

View File

@ -87,6 +87,7 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_query.h"
#include "RE_render_ext.h"
@ -251,7 +252,7 @@ struct LatticeDeformData *psys_create_lattice_deform_data(ParticleSimulationData
{
struct LatticeDeformData *lattice_deform_data = NULL;
if (psys_in_edit_mode(sim->eval_ctx->view_layer, sim->psys) == 0) {
if (psys_in_edit_mode(sim->eval_ctx->depsgraph, sim->psys) == 0) {
Object *lattice = NULL;
ModifierData *md = (ModifierData *)psys_get_modifier(sim->ob, sim->psys);
int mode = G.is_rendering ? eModifierMode_Render : eModifierMode_Realtime;
@ -288,13 +289,16 @@ void psys_enable_all(Object *ob)
psys->flag &= ~PSYS_DISABLED;
}
bool psys_in_edit_mode(ViewLayer *view_layer, ParticleSystem *psys)
bool psys_in_edit_mode(Depsgraph *depsgraph, ParticleSystem *psys)
{
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
const bool use_render_params = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
return (view_layer->basact &&
(view_layer->basact->object->mode & OB_MODE_PARTICLE_EDIT) &&
psys == psys_get_current((view_layer->basact)->object) &&
(psys->edit || psys->pointcache->edit) &&
!psys->renderdata);
!use_render_params);
}
bool psys_check_enabled(Object *ob, ParticleSystem *psys, const bool use_render_params)
@ -305,7 +309,7 @@ bool psys_check_enabled(Object *ob, ParticleSystem *psys, const bool use_render_
return 0;
psmd = psys_get_modifier(ob, psys);
if (psys->renderdata || use_render_params) {
if (use_render_params) {
if (!(psmd->modifier.mode & eModifierMode_Render))
return 0;
}
@ -621,204 +625,6 @@ void psys_free(Object *ob, ParticleSystem *psys)
}
}
/************************************************/
/* Rendering */
/************************************************/
/* these functions move away particle data and bring it back after
* rendering, to make different render settings possible without
* removing the previous data. this should be solved properly once */
void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset)
{
ParticleRenderData *data;
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
if (psys->renderdata)
return;
data = MEM_callocN(sizeof(ParticleRenderData), "ParticleRenderData");
data->child = psys->child;
data->totchild = psys->totchild;
data->pathcache = psys->pathcache;
data->pathcachebufs.first = psys->pathcachebufs.first;
data->pathcachebufs.last = psys->pathcachebufs.last;
data->totcached = psys->totcached;
data->childcache = psys->childcache;
data->childcachebufs.first = psys->childcachebufs.first;
data->childcachebufs.last = psys->childcachebufs.last;
data->totchildcache = psys->totchildcache;
if (psmd->dm_final) {
data->dm = CDDM_copy_with_tessface(psmd->dm_final);
}
data->totdmvert = psmd->totdmvert;
data->totdmedge = psmd->totdmedge;
data->totdmface = psmd->totdmface;
psys->child = NULL;
psys->pathcache = NULL;
psys->childcache = NULL;
psys->totchild = psys->totcached = psys->totchildcache = 0;
BLI_listbase_clear(&psys->pathcachebufs);
BLI_listbase_clear(&psys->childcachebufs);
copy_m4_m4(data->winmat, winmat);
mul_m4_m4m4(data->viewmat, viewmat, ob->obmat);
mul_m4_m4m4(data->mat, winmat, data->viewmat);
data->winx = winx;
data->winy = winy;
data->timeoffset = timeoffset;
psys->renderdata = data;
/* Hair can and has to be recalculated if everything isn't displayed. */
if (psys->part->disp != 100 && ELEM(psys->part->type, PART_HAIR, PART_FLUID)) {
psys->recalc |= PSYS_RECALC_RESET;
}
}
void psys_render_restore(Object *ob, ParticleSystem *psys)
{
ParticleRenderData *data;
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
float render_disp = psys_get_current_display_percentage(psys);
float disp;
data = psys->renderdata;
if (!data)
return;
if (data->elems)
MEM_freeN(data->elems);
if (psmd->dm_final) {
psmd->dm_final->needsFree = 1;
psmd->dm_final->release(psmd->dm_final);
}
if (psmd->dm_deformed) {
psmd->dm_deformed->needsFree = 1;
psmd->dm_deformed->release(psmd->dm_deformed);
psmd->dm_deformed = NULL;
}
psys_free_path_cache(psys, NULL);
if (psys->child) {
MEM_freeN(psys->child);
psys->child = 0;
psys->totchild = 0;
}
psys->child = data->child;
psys->totchild = data->totchild;
psys->pathcache = data->pathcache;
psys->pathcachebufs.first = data->pathcachebufs.first;
psys->pathcachebufs.last = data->pathcachebufs.last;
psys->totcached = data->totcached;
psys->childcache = data->childcache;
psys->childcachebufs.first = data->childcachebufs.first;
psys->childcachebufs.last = data->childcachebufs.last;
psys->totchildcache = data->totchildcache;
psmd->dm_final = data->dm;
psmd->totdmvert = data->totdmvert;
psmd->totdmedge = data->totdmedge;
psmd->totdmface = data->totdmface;
psmd->flag &= ~eParticleSystemFlag_psys_updated;
if (psmd->dm_final) {
if (!psmd->dm_final->deformedOnly) {
if (ob->derivedDeform) {
psmd->dm_deformed = CDDM_copy(ob->derivedDeform);
}
else {
psmd->dm_deformed = CDDM_from_mesh((Mesh *)ob->data);
}
DM_ensure_tessface(psmd->dm_deformed);
}
psys_calc_dmcache(ob, psmd->dm_final, psmd->dm_deformed, psys);
}
MEM_freeN(data);
psys->renderdata = NULL;
/* restore particle display percentage */
disp = psys_get_current_display_percentage(psys);
if (disp != render_disp) {
/* Hair can and has to be recalculated if everything isn't displayed. */
if (ELEM(psys->part->type, PART_HAIR, PART_FLUID)) {
psys->recalc |= PSYS_RECALC_RESET;
}
else {
PARTICLE_P;
LOOP_PARTICLES {
if (psys_frand(psys, p) > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
}
}
}
}
bool psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float *params)
{
ParticleRenderData *data;
ParticleRenderElem *elem;
float x, w, scale, alpha, lambda, t, scalemin, scalemax;
int b;
if (!(psys->renderdata && (psys->part->simplify_flag & PART_SIMPLIFY_ENABLE)))
return false;
data = psys->renderdata;
if (!data->do_simplify)
return false;
b = (data->index_mf_to_mpoly) ? DM_origindex_mface_mpoly(data->index_mf_to_mpoly, data->index_mp_to_orig, cpa->num) : cpa->num;
if (b == ORIGINDEX_NONE) {
return false;
}
elem = &data->elems[b];
lambda = elem->lambda;
t = elem->t;
scalemin = elem->scalemin;
scalemax = elem->scalemax;
if (!elem->reduce) {
scale = scalemin;
alpha = 1.0f;
}
else {
x = (elem->curchild + 0.5f) / elem->totchild;
if (x < lambda - t) {
scale = scalemax;
alpha = 1.0f;
}
else if (x >= lambda + t) {
scale = scalemin;
alpha = 0.0f;
}
else {
w = (lambda + t - x) / (2.0f * t);
scale = scalemin + (scalemax - scalemin) * w;
alpha = w;
}
}
params[0] = scale;
params[1] = alpha;
elem->curchild++;
return 1;
}
/************************************************/
/* Interpolation */
/************************************************/
@ -2050,7 +1856,7 @@ void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params
int from = PART_FROM_FACE;
totparent = (int)(totchild * part->parents * 0.3f);
if ((sim->psys->renderdata || use_render_params) && part->child_nbr && part->ren_child_nbr)
if (use_render_params && part->child_nbr && part->ren_child_nbr)
totparent *= (float)part->child_nbr / (float)part->ren_child_nbr;
/* hard limit, workaround for it being ignored above */
@ -2094,10 +1900,10 @@ static bool psys_thread_context_init_path(
psys_thread_context_init(ctx, sim);
/*---start figuring out what is actually wanted---*/
if (psys_in_edit_mode(sim->eval_ctx->view_layer, psys)) {
if (psys_in_edit_mode(sim->eval_ctx->depsgraph, psys)) {
ParticleEditSettings *pset = &scene->toolsettings->particle;
if ((psys->renderdata == 0 && use_render_params == 0) && (psys->edit == NULL || pset->flag & PE_DRAW_PART) == 0)
if ((use_render_params == 0) && (psys->edit == NULL || pset->flag & PE_DRAW_PART) == 0)
totchild = 0;
segments = 1 << pset->draw_step;
@ -2106,14 +1912,14 @@ static bool psys_thread_context_init_path(
if (totchild && part->childtype == PART_CHILD_FACES) {
totparent = (int)(totchild * part->parents * 0.3f);
if ((psys->renderdata || use_render_params) && part->child_nbr && part->ren_child_nbr)
if (use_render_params && part->child_nbr && part->ren_child_nbr)
totparent *= (float)part->child_nbr / (float)part->ren_child_nbr;
/* part->parents could still be 0 so we can't test with totparent */
between = 1;
}
if (psys->renderdata || use_render_params)
if (use_render_params)
segments = 1 << part->ren_step;
else {
totchild = (int)((float)totchild * (float)part->disp / 100.0f);
@ -2191,7 +1997,7 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp
ParticleSystem *psys = ctx->sim.psys;
ParticleSettings *part = psys->part;
ParticleCacheKey **cache = psys->childcache;
ParticleCacheKey **pcache = psys_in_edit_mode(ctx->sim.eval_ctx->view_layer, psys) && psys->edit ? psys->edit->pathcache : psys->pathcache;
ParticleCacheKey **pcache = psys_in_edit_mode(ctx->sim.eval_ctx->depsgraph, psys) && psys->edit ? psys->edit->pathcache : psys->pathcache;
ParticleCacheKey *child, *key[4];
ParticleTexture ptex;
float *cpa_fuv = 0, *par_rot = 0, rot[4];
@ -2603,7 +2409,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
float prev_tangent[3] = {0.0f, 0.0f, 0.0f}, hairmat[4][4];
float rotmat[3][3];
int k;
int segments = (int)pow(2.0, (double)((psys->renderdata || use_render_params) ? part->ren_step : part->draw_step));
int segments = (int)pow(2.0, (double)((use_render_params) ? part->ren_step : part->draw_step));
int totpart = psys->totpart;
float length, vec[3];
float *vg_effector = NULL;
@ -2615,8 +2421,8 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
return;
#if 0 /* TODO(mai): something is very wrong with these conditionals, they dont make sense and the cache isnt updating */
if (psys_in_edit_mode(sim->eval_ctx->view_layer, psys))
if (psys->renderdata == 0 && (psys->edit == NULL || pset->flag & PE_DRAW_PART) == 0)
if (psys_in_edit_mode(sim->eval_ctx->depsgraph, psys))
if ((psys->edit == NULL || pset->flag & PE_DRAW_PART) == 0)
return;
#endif
@ -3322,11 +3128,6 @@ static void default_particle_settings(ParticleSettings *part)
part->color_vec_max = 1.f;
part->draw_col = PART_DRAW_COL_MAT;
part->simplify_refsize = 1920;
part->simplify_rate = 1.0f;
part->simplify_transition = 0.1f;
part->simplify_viewport = 0.8;
if (!part->effector_weights)
part->effector_weights = BKE_add_effector_weights(NULL);
@ -3830,7 +3631,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE);
/* pind.dm disabled in editmode means we don't get effectors taken into
* account when subdividing for instance */
pind.dm = psys_in_edit_mode(sim->eval_ctx->view_layer, psys) ? NULL : psys->hair_out_dm;
pind.dm = psys_in_edit_mode(sim->eval_ctx->depsgraph, psys) ? NULL : psys->hair_out_dm;
init_particle_interpolation(sim->ob, psys, pa, &pind);
do_particle_interpolation(psys, p, pa, t, &pind, state);

View File

@ -57,7 +57,7 @@
#include "BKE_object.h"
#include "BKE_particle.h"
static int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot);
#include "DEG_depsgraph_query.h"
static void alloc_child_particles(ParticleSystem *psys, int tot)
{
@ -80,12 +80,12 @@ static void alloc_child_particles(ParticleSystem *psys, int tot)
}
}
static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *finaldm, DerivedMesh *deformdm, ParticleSystem *psys)
static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *finaldm, DerivedMesh *deformdm, ParticleSystem *psys, const bool use_render_params)
{
ChildParticle *cpa = NULL;
int i, p;
int child_nbr= psys_get_child_number(scene, psys);
int totpart= psys_get_tot_child(scene, psys);
int child_nbr= psys_get_child_number(scene, psys, use_render_params);
int totpart= psys_get_tot_child(scene, psys, use_render_params);
alloc_child_particles(psys, totpart);
@ -738,16 +738,10 @@ static void exec_distribute_child(TaskPool * __restrict UNUSED(pool), void *task
/* RNG skipping at the beginning */
cpa = psys->child;
for (p = 0; p < task->begin; ++p, ++cpa) {
if (task->ctx->skip) /* simplification skip */
BLI_rng_skip(task->rng, PSYS_RND_DIST_SKIP * task->ctx->skip[p]);
BLI_rng_skip(task->rng, PSYS_RND_DIST_SKIP);
}
for (; p < task->end; ++p, ++cpa) {
if (task->ctx->skip) /* simplification skip */
BLI_rng_skip(task->rng, PSYS_RND_DIST_SKIP * task->ctx->skip[p]);
distribute_children_exec(task, cpa, p);
}
}
@ -774,11 +768,15 @@ static int distribute_compare_orig_index(const void *p1, const void *p2, void *u
return 1;
}
static void distribute_invalid(Scene *scene, ParticleSystem *psys, int from)
static void distribute_invalid(ParticleSimulationData *sim, int from)
{
Scene *scene = sim->scene;
ParticleSystem *psys = sim->psys;
const bool use_render_params = (DEG_get_mode(sim->eval_ctx->depsgraph) == DAG_EVAL_RENDER);
if (from == PART_FROM_CHILD) {
ChildParticle *cpa;
int p, totchild = psys_get_tot_child(scene, psys);
int p, totchild = psys_get_tot_child(scene, psys, use_render_params);
if (psys->child && totchild) {
for (p=0,cpa=psys->child; p<totchild; p++,cpa++) {
@ -841,13 +839,15 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
*/
psys_thread_context_init(ctx, sim);
const bool use_render_params = (DEG_get_mode(sim->eval_ctx->depsgraph) == DAG_EVAL_RENDER);
/* First handle special cases */
if (from == PART_FROM_CHILD) {
/* Simple children */
if (part->childtype != PART_CHILD_FACES) {
BLI_srandom(31415926 + psys->seed + psys->child_seed);
distribute_simple_children(scene, ob, finaldm, sim->psmd->dm_deformed, psys);
distribute_simple_children(scene, ob, finaldm, sim->psmd->dm_deformed, psys, use_render_params);
return 0;
}
}
@ -895,7 +895,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
BLI_kdtree_balance(tree);
totpart = psys_get_tot_child(scene, psys);
totpart = psys_get_tot_child(scene, psys, use_render_params);
cfrom = from = PART_FROM_FACE;
}
else {
@ -938,7 +938,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
totelem = (from == PART_FROM_VERT) ? dm->getNumVerts(dm) : dm->getNumTessFaces(dm);
if (totelem == 0) {
distribute_invalid(scene, psys, children ? PART_FROM_CHILD : 0);
distribute_invalid(sim, children ? PART_FROM_CHILD : 0);
if (G.debug & G_DEBUG)
fprintf(stderr,"Particle distribution error: Nothing to emit from!\n");
@ -1082,7 +1082,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
totmapped = i_mapped;
/* Finally assign elements to particles */
if ((part->flag & PART_TRAND) || (part->simplify_flag & PART_SIMPLIFY_ENABLE)) {
if (part->flag & PART_TRAND) {
for (p = 0; p < totpart; p++) {
/* In theory element_sum[totmapped - 1] should be 1.0,
* but due to float errors this is not necessarily always true, so scale pos accordingly. */
@ -1176,7 +1176,6 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
ctx->tpars= tpars;
if (children) {
totpart= psys_render_simplify_distribution(ctx, totpart);
alloc_child_particles(psys, totpart);
}
@ -1235,7 +1234,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
/* ready for future use, to emit particles without geometry */
static void distribute_particles_on_shape(ParticleSimulationData *sim, int UNUSED(from))
{
distribute_invalid(sim->scene, sim->psys, 0);
distribute_invalid(sim, 0);
fprintf(stderr,"Shape emission not yet possible!\n");
}
@ -1255,250 +1254,8 @@ void distribute_particles(ParticleSimulationData *sim, int from)
distribute_particles_on_shape(sim, from);
if (distr_error) {
distribute_invalid(sim->scene, sim->psys, from);
distribute_invalid(sim, from);
fprintf(stderr,"Particle distribution error!\n");
}
}
/* ======== Simplify ======== */
static float psys_render_viewport_falloff(double rate, float dist, float width)
{
return pow(rate, dist / width);
}
static float psys_render_projected_area(ParticleSystem *psys, const float center[3], float area, double vprate, float *viewport)
{
ParticleRenderData *data = psys->renderdata;
float co[4], view[3], ortho1[3], ortho2[3], w, dx, dy, radius;
/* transform to view space */
copy_v3_v3(co, center);
co[3] = 1.0f;
mul_m4_v4(data->viewmat, co);
/* compute two vectors orthogonal to view vector */
normalize_v3_v3(view, co);
ortho_basis_v3v3_v3(ortho1, ortho2, view);
/* compute on screen minification */
w = co[2] * data->winmat[2][3] + data->winmat[3][3];
dx = data->winx * ortho2[0] * data->winmat[0][0];
dy = data->winy * ortho2[1] * data->winmat[1][1];
w = sqrtf(dx * dx + dy * dy) / w;
/* w squared because we are working with area */
area = area * w * w;
/* viewport of the screen test */
/* project point on screen */
mul_m4_v4(data->winmat, co);
if (co[3] != 0.0f) {
co[0] = 0.5f * data->winx * (1.0f + co[0] / co[3]);
co[1] = 0.5f * data->winy * (1.0f + co[1] / co[3]);
}
/* screen space radius */
radius = sqrtf(area / (float)M_PI);
/* make smaller using fallof once over screen edge */
*viewport = 1.0f;
if (co[0] + radius < 0.0f)
*viewport *= psys_render_viewport_falloff(vprate, -(co[0] + radius), data->winx);
else if (co[0] - radius > data->winx)
*viewport *= psys_render_viewport_falloff(vprate, (co[0] - radius) - data->winx, data->winx);
if (co[1] + radius < 0.0f)
*viewport *= psys_render_viewport_falloff(vprate, -(co[1] + radius), data->winy);
else if (co[1] - radius > data->winy)
*viewport *= psys_render_viewport_falloff(vprate, (co[1] - radius) - data->winy, data->winy);
return area;
}
/* BMESH_TODO, for orig face data, we need to use MPoly */
static int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
{
DerivedMesh *dm = ctx->dm;
Mesh *me = (Mesh *)(ctx->sim.ob->data);
MFace *mf, *mface;
MVert *mvert;
ParticleRenderData *data;
ParticleRenderElem *elems, *elem;
ParticleSettings *part = ctx->sim.psys->part;
float *facearea, (*facecenter)[3], size[3], fac, powrate, scaleclamp;
float co1[3], co2[3], co3[3], co4[3], lambda, arearatio, t, area, viewport;
double vprate;
int *facetotvert;
int a, b, totorigface, totface, newtot, skipped;
/* double lookup */
const int *index_mf_to_mpoly;
const int *index_mp_to_orig;
if (part->ren_as != PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND))
return tot;
if (!ctx->sim.psys->renderdata)
return tot;
data = ctx->sim.psys->renderdata;
if (data->timeoffset)
return 0;
if (!(part->simplify_flag & PART_SIMPLIFY_ENABLE))
return tot;
mvert = dm->getVertArray(dm);
mface = dm->getTessFaceArray(dm);
totface = dm->getNumTessFaces(dm);
totorigface = me->totpoly;
if (totface == 0 || totorigface == 0)
return tot;
index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
if (index_mf_to_mpoly == NULL) {
index_mp_to_orig = NULL;
}
facearea = MEM_callocN(sizeof(float) * totorigface, "SimplifyFaceArea");
facecenter = MEM_callocN(sizeof(float[3]) * totorigface, "SimplifyFaceCenter");
facetotvert = MEM_callocN(sizeof(int) * totorigface, "SimplifyFaceArea");
elems = MEM_callocN(sizeof(ParticleRenderElem) * totorigface, "SimplifyFaceElem");
if (data->elems)
MEM_freeN(data->elems);
data->do_simplify = true;
data->elems = elems;
data->index_mf_to_mpoly = index_mf_to_mpoly;
data->index_mp_to_orig = index_mp_to_orig;
/* compute number of children per original face */
for (a = 0; a < tot; a++) {
b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, ctx->index[a]) : ctx->index[a];
if (b != ORIGINDEX_NONE) {
elems[b].totchild++;
}
}
/* compute areas and centers of original faces */
for (mf = mface, a = 0; a < totface; a++, mf++) {
b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
if (b != ORIGINDEX_NONE) {
copy_v3_v3(co1, mvert[mf->v1].co);
copy_v3_v3(co2, mvert[mf->v2].co);
copy_v3_v3(co3, mvert[mf->v3].co);
add_v3_v3(facecenter[b], co1);
add_v3_v3(facecenter[b], co2);
add_v3_v3(facecenter[b], co3);
if (mf->v4) {
copy_v3_v3(co4, mvert[mf->v4].co);
add_v3_v3(facecenter[b], co4);
facearea[b] += area_quad_v3(co1, co2, co3, co4);
facetotvert[b] += 4;
}
else {
facearea[b] += area_tri_v3(co1, co2, co3);
facetotvert[b] += 3;
}
}
}
for (a = 0; a < totorigface; a++)
if (facetotvert[a] > 0)
mul_v3_fl(facecenter[a], 1.0f / facetotvert[a]);
/* for conversion from BU area / pixel area to reference screen size */
BKE_mesh_texspace_get(me, 0, 0, size);
fac = ((size[0] + size[1] + size[2]) / 3.0f) / part->simplify_refsize;
fac = fac * fac;
powrate = log(0.5f) / log(part->simplify_rate * 0.5f);
if (part->simplify_flag & PART_SIMPLIFY_VIEWPORT)
vprate = pow(1.0f - part->simplify_viewport, 5.0);
else
vprate = 1.0;
/* set simplification parameters per original face */
for (a = 0, elem = elems; a < totorigface; a++, elem++) {
area = psys_render_projected_area(ctx->sim.psys, facecenter[a], facearea[a], vprate, &viewport);
arearatio = fac * area / facearea[a];
if ((arearatio < 1.0f || viewport < 1.0f) && elem->totchild) {
/* lambda is percentage of elements to keep */
lambda = (arearatio < 1.0f) ? powf(arearatio, powrate) : 1.0f;
lambda *= viewport;
lambda = MAX2(lambda, 1.0f / elem->totchild);
/* compute transition region */
t = part->simplify_transition;
elem->t = (lambda - t < 0.0f) ? lambda : (lambda + t > 1.0f) ? 1.0f - lambda : t;
elem->reduce = 1;
/* scale at end and beginning of the transition region */
elem->scalemax = (lambda + t < 1.0f) ? 1.0f / lambda : 1.0f / (1.0f - elem->t * elem->t / t);
elem->scalemin = (lambda + t < 1.0f) ? 0.0f : elem->scalemax * (1.0f - elem->t / t);
elem->scalemin = sqrtf(elem->scalemin);
elem->scalemax = sqrtf(elem->scalemax);
/* clamp scaling */
scaleclamp = (float)min_ii(elem->totchild, 10);
elem->scalemin = MIN2(scaleclamp, elem->scalemin);
elem->scalemax = MIN2(scaleclamp, elem->scalemax);
/* extend lambda to include transition */
lambda = lambda + elem->t;
if (lambda > 1.0f)
lambda = 1.0f;
}
else {
lambda = arearatio;
elem->scalemax = 1.0f; //sqrt(lambda);
elem->scalemin = 1.0f; //sqrt(lambda);
elem->reduce = 0;
}
elem->lambda = lambda;
elem->scalemin = sqrtf(elem->scalemin);
elem->scalemax = sqrtf(elem->scalemax);
elem->curchild = 0;
}
MEM_freeN(facearea);
MEM_freeN(facecenter);
MEM_freeN(facetotvert);
/* move indices and set random number skipping */
ctx->skip = MEM_callocN(sizeof(int) * tot, "SimplificationSkip");
skipped = 0;
for (a = 0, newtot = 0; a < tot; a++) {
b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, ctx->index[a]) : ctx->index[a];
if (b != ORIGINDEX_NONE) {
if (elems[b].curchild++ < ceil(elems[b].lambda * elems[b].totchild)) {
ctx->index[newtot] = ctx->index[a];
ctx->skip[newtot] = skipped;
skipped = 0;
newtot++;
}
else skipped++;
}
else skipped++;
}
for (a = 0, elem = elems; a < totorigface; a++, elem++)
elem->curchild = 0;
return newtot;
}

View File

@ -90,11 +90,11 @@
#include "BKE_bvhutils.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
#include "PIL_time.h"
#include "RE_shader_ext.h"
#include "DEG_depsgraph.h"
/* fluid sim particle import */
#ifdef WITH_MOD_FLUID
@ -122,11 +122,11 @@ static int particles_are_dynamic(ParticleSystem *psys)
return ELEM(psys->part->phystype, PART_PHYS_NEWTON, PART_PHYS_BOIDS, PART_PHYS_FLUID);
}
float psys_get_current_display_percentage(ParticleSystem *psys)
float psys_get_current_display_percentage(ParticleSystem *psys, const bool use_render_params)
{
ParticleSettings *part=psys->part;
if ((psys->renderdata && !particles_are_dynamic(psys)) || /* non-dynamic particles can be rendered fully */
if ((use_render_params && !particles_are_dynamic(psys)) || /* non-dynamic particles can be rendered fully */
(part->child_nbr && part->childtype) || /* display percentage applies to children */
(psys->pointcache->flag & PTCACHE_BAKING)) /* baking is always done with full amount */
{
@ -286,24 +286,24 @@ static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
}
}
int psys_get_child_number(Scene *scene, ParticleSystem *psys)
int psys_get_child_number(Scene *scene, ParticleSystem *psys, const bool use_render_params)
{
int nbr;
if (!psys->part->childtype)
return 0;
if (psys->renderdata)
if (use_render_params)
nbr= psys->part->ren_child_nbr;
else
nbr= psys->part->child_nbr;
return get_render_child_particle_number(&scene->r, nbr, psys->renderdata != NULL);
return get_render_child_particle_number(&scene->r, nbr, use_render_params);
}
int psys_get_tot_child(Scene *scene, ParticleSystem *psys)
int psys_get_tot_child(Scene *scene, ParticleSystem *psys, const bool use_render_params)
{
return psys->totpart*psys_get_child_number(scene, psys);
return psys->totpart*psys_get_child_number(scene, psys, use_render_params);
}
/************************************************/
@ -512,7 +512,6 @@ void psys_thread_context_free(ParticleThreadContext *ctx)
if (ctx->jitoff) MEM_freeN(ctx->jitoff);
if (ctx->weight) MEM_freeN(ctx->weight);
if (ctx->index) MEM_freeN(ctx->index);
if (ctx->skip) MEM_freeN(ctx->skip);
if (ctx->seams) MEM_freeN(ctx->seams);
//if (ctx->vertpart) MEM_freeN(ctx->vertpart);
BLI_kdtree_free(ctx->tree);
@ -2908,7 +2907,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons
#endif
int distr=0, alloc=0, skip=0;
if ((psys->part->childtype && psys->totchild != psys_get_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
if ((psys->part->childtype && psys->totchild != psys_get_tot_child(sim->scene, psys, use_render_params)) || psys->recalc&PSYS_RECALC_RESET)
alloc=1;
if (alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->ob->mode & OB_MODE_WEIGHT_PAINT)))
@ -2918,7 +2917,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons
if (alloc)
realloc_particles(sim, sim->psys->totpart);
if (psys_get_tot_child(sim->scene, psys)) {
if (psys_get_tot_child(sim->scene, psys, use_render_params)) {
/* don't generate children while computing the hair keys */
if (!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) {
distribute_particles(sim, PART_FROM_CHILD);
@ -2935,14 +2934,14 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons
skip = 1; /* only hair, keyed and baked stuff can have paths */
else if (part->ren_as != PART_DRAW_PATH && !(part->type==PART_HAIR && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)))
skip = 1; /* particle visualization must be set as path */
else if (!psys->renderdata) {
else {
if (part->draw_as != PART_DRAW_REND)
skip = 1; /* draw visualization */
else if (psys->pointcache->flag & PTCACHE_BAKING)
skip = 1; /* no need to cache paths while baking dynamics */
#if 0 /* TODO(mai): something is very wrong with these conditionals, they dont make sense and the cache isnt updating */
else if (psys_in_edit_mode(sim->eval_ctx->view_layer, psys)) {
else if (psys_in_edit_mode(sim->eval_ctx->depsgraph, psys)) {
if ((pset->flag & PE_DRAW_PART)==0)
skip = 1;
else if (part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0)
@ -3224,7 +3223,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra, const bool use_re
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
PARTICLE_P;
float disp = psys_get_current_display_percentage(psys);
float disp = psys_get_current_display_percentage(psys, use_render_params);
LOOP_PARTICLES {
pa->size = part->size;
@ -3740,13 +3739,13 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
free_collider_cache(&sim->colliders);
BLI_rng_free(rng);
}
static void update_children(ParticleSimulationData *sim)
static void update_children(ParticleSimulationData *sim, const bool use_render_params)
{
if ((sim->psys->part->type == PART_HAIR) && (sim->psys->flag & PSYS_HAIR_DONE)==0)
/* don't generate children while growing hair - waste of time */
psys_free_children(sim->psys);
else if (sim->psys->part->childtype) {
if (sim->psys->totchild != psys_get_tot_child(sim->scene, sim->psys))
if (sim->psys->totchild != psys_get_tot_child(sim->scene, sim->psys, use_render_params))
distribute_particles(sim, PART_FROM_CHILD);
else {
/* Children are up to date, nothing to do. */
@ -3756,7 +3755,7 @@ static void update_children(ParticleSimulationData *sim)
psys_free_children(sim->psys);
}
/* updates cached particles' alive & other flags etc..*/
static void cached_step(ParticleSimulationData *sim, float cfra)
static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_render_params)
{
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
@ -3766,7 +3765,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
psys_update_effectors(sim);
disp= psys_get_current_display_percentage(psys);
disp= psys_get_current_display_percentage(psys, use_render_params);
LOOP_PARTICLES {
psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra);
@ -3988,8 +3987,8 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_
int cache_result = BKE_ptcache_read(pid, cache_cfra, true);
if (ELEM(cache_result, PTCACHE_READ_EXACT, PTCACHE_READ_INTERPOLATED)) {
cached_step(sim, cfra);
update_children(sim);
cached_step(sim, cfra, use_render_params);
update_children(sim, use_render_params);
psys_update_path_cache(sim, cfra, use_render_params);
BKE_ptcache_validate(cache, (int)cache_cfra);
@ -4006,7 +4005,7 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_
}
else if (cache_result == PTCACHE_READ_OLD) {
psys->cfra = (float)cache->simframe;
cached_step(sim, psys->cfra);
cached_step(sim, psys->cfra, use_render_params);
}
/* if on second frame, write cache for first frame */
@ -4018,7 +4017,7 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_
/* 3. do dynamics */
/* set particles to be not calculated TODO: can't work with pointcache */
disp= psys_get_current_display_percentage(psys);
disp= psys_get_current_display_percentage(psys, use_render_params);
LOOP_PARTICLES {
if (psys_frand(psys, p) > disp)
@ -4074,7 +4073,7 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_
BKE_ptcache_write(pid, (int)cache_cfra);
}
update_children(sim);
update_children(sim, use_render_params);
/* cleanup */
if (psys->lattice_deform_data) {
@ -4317,7 +4316,7 @@ void particle_system_update(const struct EvaluationContext *eval_ctx, Scene *sce
case PART_PHYS_KEYED:
{
PARTICLE_P;
float disp = psys_get_current_display_percentage(psys);
float disp = psys_get_current_display_percentage(psys, use_render_params);
bool free_unexisting = false;
/* Particles without dynamics haven't been reset yet because they don't use pointcache */
@ -4379,8 +4378,7 @@ void particle_system_update(const struct EvaluationContext *eval_ctx, Scene *sce
psys->recalc = 0;
/* save matrix for duplicators, at rendertime the actual dupliobject's matrix is used so don't update! */
if (psys->renderdata==0)
invert_m4_m4(psys->imat, ob->obmat);
invert_m4_m4(psys->imat, ob->obmat);
BKE_particle_batch_cache_dirty(psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
}

View File

@ -4526,7 +4526,6 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
BLI_listbase_clear(&psys->pathcachebufs);
BLI_listbase_clear(&psys->childcachebufs);
psys->pdd = NULL;
psys->renderdata = NULL;
if (psys->clmd) {
psys->clmd = newdataadr(fd, psys->clmd);

View File

@ -2770,13 +2770,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
for (part = main->particle.first; part; part = part->id.next) {
if (part->ren_child_nbr == 0)
part->ren_child_nbr = part->child_nbr;
if (part->simplify_refsize == 0) {
part->simplify_refsize = 1920;
part->simplify_rate = 1.0f;
part->simplify_transition = 0.1f;
part->simplify_viewport = 0.8f;
}
}
for (wrld = main->world.first; wrld; wrld = wrld->id.next) {

View File

@ -627,7 +627,7 @@ static Mesh *bake_mesh_new_from_object(EvaluationContext *eval_ctx, Main *bmain,
{
ED_object_editmode_load(ob);
Mesh *me = BKE_mesh_new_from_object(eval_ctx, bmain, scene, ob, 1, 2, 0, 0);
Mesh *me = BKE_mesh_new_from_object(eval_ctx, bmain, scene, ob, 1, 0, 0);
if (me->flag & ME_AUTOSMOOTH) {
BKE_mesh_split_faces(me, true);
}

View File

@ -5937,7 +5937,7 @@ static void draw_new_particle_system(
if (pars == NULL) return;
/* don't draw normal paths in edit mode */
if (psys_in_edit_mode(eval_ctx->view_layer, psys) && (pset->flag & PE_DRAW_PART) == 0)
if (psys_in_edit_mode(eval_ctx->depsgraph, psys) && (pset->flag & PE_DRAW_PART) == 0)
return;
if (part->draw_as == PART_DRAW_REND)

View File

@ -121,7 +121,6 @@ NodeGroup *BlenderFileLoader::Load()
_re->scene,
ob,
apply_modifiers,
eModifierMode_Render,
calc_tessface,
calc_undeformed);

View File

@ -188,11 +188,6 @@ typedef struct ParticleSettings {
/* draw color */
float color_vec_max;
/* simplification */
short simplify_flag, simplify_refsize;
float simplify_rate, simplify_transition;
float simplify_viewport;
/* time and emission */
float sta, end, lifetime, randlife;
float timetweak, courant_target;
@ -313,9 +308,6 @@ typedef struct ParticleSystem {
short vgroup[13], vg_neg, rt3; /* vertex groups, 0==disable, 1==starting index */
char pad[6];
/* temporary storage during render */
struct ParticleRenderData *renderdata;
/* point cache */
struct PointCache *pointcache;
struct ListBase ptcaches;

View File

@ -35,6 +35,7 @@
#define RNA_MAGIC ((int)~0)
struct Depsgraph;
struct FreestyleSettings;
struct ID;
struct IDOverrideStatic;
@ -473,8 +474,8 @@ PointerRNA rna_pointer_inherit_refine(struct PointerRNA *ptr, struct StructRNA *
int rna_parameter_size(struct PropertyRNA *parm);
struct Mesh *rna_Main_meshes_new_from_object(
struct Main *bmain, struct ReportList *reports, struct Scene *sce, struct ViewLayer *view_layer,
struct Object *ob, int apply_modifiers, int settings, int calc_tessface, int calc_undeformed);
struct Main *bmain, struct ReportList *reports, struct Depsgraph *depsgraph,
struct Object *ob, int apply_modifiers, int calc_tessface, int calc_undeformed);
/* XXX, these should not need to be defined here~! */
struct MTex *rna_mtex_texture_slots_add(struct ID *self, struct bContext *C, struct ReportList *reports);

View File

@ -298,27 +298,17 @@ static Mesh *rna_Main_meshes_new(Main *bmain, const char *name)
}
/* copied from Mesh_getFromObject and adapted to RNA interface */
/* settings: 1 - preview, 2 - render */
Mesh *rna_Main_meshes_new_from_object(
Main *bmain, ReportList *reports, Scene *sce, ViewLayer *view_layer,
Object *ob, int apply_modifiers, int settings, int calc_tessface, int calc_undeformed)
Main *bmain, ReportList *reports, Depsgraph *depsgraph,
Object *ob, int apply_modifiers, int calc_tessface, int calc_undeformed)
{
EvaluationContext eval_ctx;
Scene *sce = DEG_get_evaluated_scene(depsgraph);
/* XXX: This should never happen, but render pipeline is not ready to give
* proper view_layer, and will always pass NULL here. For until we port
* pipeline form SceneRenderLayer to ViewLayer we have this stub to prevent
* some obvious crashes.
* - sergey -
*/
if (view_layer == NULL) {
view_layer = sce->view_layers.first;
}
DEG_evaluation_context_init(&eval_ctx, settings);
eval_ctx.ctime = (float)sce->r.cfra + sce->r.subframe;
eval_ctx.view_layer = view_layer;
eval_ctx.depsgraph = BKE_scene_get_depsgraph(sce, view_layer, false);
DEG_evaluation_context_init(&eval_ctx, DEG_get_mode(depsgraph));
eval_ctx.ctime = DEG_get_ctime(depsgraph);
eval_ctx.view_layer = DEG_get_evaluated_view_layer(depsgraph);
eval_ctx.depsgraph = depsgraph;
switch (ob->type) {
case OB_FONT:
@ -332,7 +322,7 @@ Mesh *rna_Main_meshes_new_from_object(
return NULL;
}
return BKE_mesh_new_from_object(&eval_ctx, bmain, sce, ob, apply_modifiers, settings, calc_tessface, calc_undeformed);
return BKE_mesh_new_from_object(&eval_ctx, bmain, sce, ob, apply_modifiers, calc_tessface, calc_undeformed);
}
static Lamp *rna_Main_lamps_new(Main *bmain, const char *name, int type)
@ -893,12 +883,6 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop)
PropertyRNA *parm;
PropertyRNA *prop;
static const EnumPropertyItem mesh_type_items[] = {
{eModifierMode_Realtime, "PREVIEW", 0, "Preview", "Apply modifier preview settings"},
{eModifierMode_Render, "RENDER", 0, "Render", "Apply modifier render settings"},
{0, NULL, 0, NULL, NULL}
};
RNA_def_property_srna(cprop, "BlendDataMeshes");
srna = RNA_def_struct(brna, "BlendDataMeshes", NULL);
RNA_def_struct_sdna(srna, "Main");
@ -915,16 +899,12 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop)
func = RNA_def_function(srna, "new_from_object", "rna_Main_meshes_new_from_object");
RNA_def_function_ui_description(func, "Add a new mesh created from object with modifiers applied");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene within which to evaluate modifiers");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "Scene layer within which to evaluate modifiers");
parm = RNA_def_pointer(func, "depsgraph", "Depsgraph", "Dependency Graph", "Evaluated dependency graph within wich to evaluate modifiers");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_pointer(func, "object", "Object", "", "Object to create mesh from");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_boolean(func, "apply_modifiers", 0, "", "Apply modifiers");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Modifier settings to apply");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_boolean(func, "calc_tessface", true, "Calculate Tessellation", "Calculate tessellation faces");
RNA_def_boolean(func, "calc_undeformed", false, "Calculate Undeformed", "Calculate undeformed vertex coordinates");
parm = RNA_def_pointer(func, "mesh", "Mesh", "",

View File

@ -67,6 +67,7 @@
#include "NOD_composite.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
const EnumPropertyItem rna_enum_node_socket_in_out_items[] = {
{ SOCK_IN, "IN", 0, "Input", "" },
@ -3134,8 +3135,7 @@ static int point_density_vertex_color_source_from_shader(NodeShaderTexPointDensi
}
void rna_ShaderNodePointDensity_density_cache(bNode *self,
Depsgraph *depsgraph,
int settings)
Depsgraph *depsgraph)
{
NodeShaderTexPointDensity *shader_point_density = self->storage;
PointDensity *pd = &shader_point_density->pd;
@ -3147,8 +3147,7 @@ void rna_ShaderNodePointDensity_density_cache(bNode *self,
EvaluationContext eval_ctx;
DEG_evaluation_context_init_from_depsgraph(&eval_ctx,
depsgraph,
settings == 1 ? DAG_EVAL_RENDER :
DAG_EVAL_VIEWPORT);
DEG_get_mode(depsgraph));
/* Make sure there's no cached data. */
BKE_texture_pointdensity_free_data(pd);
@ -3184,7 +3183,6 @@ void rna_ShaderNodePointDensity_density_cache(bNode *self,
void rna_ShaderNodePointDensity_density_calc(bNode *self,
Depsgraph *depsgraph,
int settings,
int *length,
float **values)
{
@ -3200,8 +3198,7 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self,
EvaluationContext eval_ctx;
DEG_evaluation_context_init_from_depsgraph(&eval_ctx,
depsgraph,
settings == 1 ? DAG_EVAL_RENDER :
DAG_EVAL_VIEWPORT);
DEG_get_mode(depsgraph));
/* TODO(sergey): Will likely overflow, but how to pass size_t via RNA? */
*length = 4 * resolution * resolution * resolution;
@ -3224,7 +3221,6 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self,
void rna_ShaderNodePointDensity_density_minmax(bNode *self,
Depsgraph *depsgraph,
int settings,
float r_min[3],
float r_max[3])
{
@ -3240,8 +3236,7 @@ void rna_ShaderNodePointDensity_density_minmax(bNode *self,
EvaluationContext eval_ctx;
DEG_evaluation_context_init_from_depsgraph(&eval_ctx,
depsgraph,
settings == 1 ? DAG_EVAL_RENDER :
DAG_EVAL_VIEWPORT);
DEG_get_mode(depsgraph));
RE_point_density_minmax(&eval_ctx, pd, r_min, r_max);
}
@ -4165,13 +4160,6 @@ static void def_sh_tex_pointdensity(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
/* TODO(sergey): Use some mnemonic names for the hardcoded values here. */
static const EnumPropertyItem calc_mode_items[] = {
{0, "VIEWPORT", 0, "Viewport", "Canculate density using viewport settings"},
{1, "RENDER", 0, "Render", "Canculate duplis using render settings"},
{0, NULL, 0, NULL, NULL}
};
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "id");
RNA_def_property_struct_type(prop, "Object");
@ -4234,12 +4222,10 @@ static void def_sh_tex_pointdensity(StructRNA *srna)
func = RNA_def_function(srna, "cache_point_density", "rna_ShaderNodePointDensity_density_cache");
RNA_def_function_ui_description(func, "Cache point density data for later calculation");
RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "");
RNA_def_enum(func, "settings", calc_mode_items, 1, "", "Calculate density for rendering");
func = RNA_def_function(srna, "calc_point_density", "rna_ShaderNodePointDensity_density_calc");
RNA_def_function_ui_description(func, "Calculate point density");
RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "");
RNA_def_enum(func, "settings", calc_mode_items, 1, "", "Calculate density for rendering");
/* TODO, See how array size of 0 works, this shouldnt be used. */
parm = RNA_def_float_array(func, "rgba_values", 1, NULL, 0, 0, "", "RGBA Values", 0, 0);
RNA_def_parameter_flags(parm, PROP_DYNAMIC, 0);
@ -4248,7 +4234,6 @@ static void def_sh_tex_pointdensity(StructRNA *srna)
func = RNA_def_function(srna, "calc_point_density_minmax", "rna_ShaderNodePointDensity_density_minmax");
RNA_def_function_ui_description(func, "Calculate point density");
RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "");
RNA_def_enum(func, "settings", calc_mode_items, 1, "", "Calculate density for rendering");
parm = RNA_def_property(func, "min", PROP_FLOAT, PROP_COORDS);
RNA_def_property_array(parm, 3);
RNA_def_parameter_flags(parm, PROP_THICK_WRAP, 0);

View File

@ -197,12 +197,12 @@ static void rna_Object_camera_fit_coords(
/* copied from Mesh_getFromObject and adapted to RNA interface */
/* settings: 0 - preview, 1 - render */
static Mesh *rna_Object_to_mesh(
Object *ob, bContext *C, ReportList *reports, Scene *sce, ViewLayer *view_layer,
int apply_modifiers, int settings, int calc_tessface, int calc_undeformed)
Object *ob, bContext *C, ReportList *reports, Depsgraph *depsgraph,
int apply_modifiers, int calc_tessface, int calc_undeformed)
{
Main *bmain = CTX_data_main(C);
return rna_Main_meshes_new_from_object(bmain, reports, sce, view_layer, ob, apply_modifiers, settings, calc_tessface, calc_undeformed);
return rna_Main_meshes_new_from_object(bmain, reports, depsgraph, ob, apply_modifiers, calc_tessface, calc_undeformed);
}
static PointerRNA rna_Object_shape_key_add(Object *ob, bContext *C, ReportList *reports,
@ -547,14 +547,10 @@ void RNA_api_object(StructRNA *srna)
func = RNA_def_function(srna, "to_mesh", "rna_Object_to_mesh");
RNA_def_function_ui_description(func, "Create a Mesh data-block with modifiers applied");
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene within which to evaluate modifiers");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "Scene layer within which to evaluate modifiers");
parm = RNA_def_pointer(func, "depsgraph", "Depsgraph", "Dependency Graph", "Evaluated dependency graph within wich to evaluate modifiers");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_boolean(func, "apply_modifiers", 0, "", "Apply modifiers");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Modifier settings to apply");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_boolean(func, "calc_tessface", true, "Calculate Tessellation", "Calculate tessellation faces");
RNA_def_boolean(func, "calc_undeformed", false, "Calculate Undeformed", "Calculate undeformed vertex coordinates");
parm = RNA_def_pointer(func, "mesh", "Mesh", "",

View File

@ -325,27 +325,18 @@ static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *o
ParticleData *pars = NULL;
ParticleCacheKey *cache = NULL;
int totchild = 0;
int path_nbr = 0;
int totpart;
int max_k = 0;
int step_nbr = 0;
if (particlesystem == NULL)
return;
part = particlesystem->part;
pars = particlesystem->particles;
totpart = particlesystem->totcached;
totchild = particlesystem->totchildcache;
if (particlesystem->renderdata) {
step_nbr = part->ren_step;
totchild = particlesystem->totchild;
}
else {
step_nbr = part->draw_step;
totchild = (int)((float)particlesystem->totchild * (float)(part->disp) / 100.0f);
}
if (part == NULL || pars == NULL || !psys_check_enabled(object, particlesystem, particlesystem->renderdata != NULL))
if (part == NULL || pars == NULL)
return;
if (part->ren_as == PART_DRAW_OB || part->ren_as == PART_DRAW_GR || part->ren_as == PART_DRAW_NOT)
@ -355,47 +346,28 @@ static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *o
if (part->type == PART_HAIR && !particlesystem->childcache)
totchild = 0;
totpart = particlesystem->totpart;
if (particle_no >= totpart + totchild)
return;
if (part->ren_as == PART_DRAW_PATH && particlesystem->pathcache)
path_nbr = 1 << step_nbr;
if (part->kink == PART_KINK_SPIRAL)
path_nbr += part->kink_extra_steps;
if (particle_no < totpart) {
cache = particlesystem->pathcache[particle_no];
max_k = (int)cache->segments;
}
else if (particle_no < totpart + totchild) {
cache = particlesystem->childcache[particle_no - totpart];
if (path_nbr) {
cache = particlesystem->pathcache[particle_no];
if (cache->segments < 0)
max_k = 0;
else
max_k = (int)cache->segments;
}
}
else {
if (path_nbr) {
cache = particlesystem->childcache[particle_no - totpart];
if (cache->segments < 0)
max_k = 0;
else
max_k = (int)cache->segments;
}
return;
}
/*strands key loop data stored in cache + step->co*/
if (path_nbr) {
if (step >= 0 && step <= path_nbr) {
if (step <= max_k) {
copy_v3_v3(n_co, (cache + step)->co);
mul_m4_v3(particlesystem->imat, n_co);
mul_m4_v3(object->obmat, n_co);
}
}
/* Strands key loop data stored in cache + step->co. */
if (step >= 0 && step <= max_k) {
copy_v3_v3(n_co, (cache + step)->co);
mul_m4_v3(particlesystem->imat, n_co);
mul_m4_v3(object->obmat, n_co);
}
}
@ -461,20 +433,13 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys
}
part = particlesystem->part;
if (particlesystem->renderdata) {
totchild = particlesystem->totchild;
}
else {
totchild = (int)((float)particlesystem->totchild * (float)(part->disp) / 100.0f);
}
totpart = particlesystem->totcached;
totchild = particlesystem->totchildcache;
/* can happen for disconnected/global hair */
if (part->type == PART_HAIR && !particlesystem->childcache)
totchild = 0;
totpart = particlesystem->totpart;
if (particle_no >= totpart + totchild)
return num;
@ -614,36 +579,6 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, R
}
}
static void rna_ParticleSystem_set_resolution(ParticleSystem *particlesystem, Scene *scene, ViewLayer *view_layer, Object *object, int resolution)
{
EvaluationContext eval_ctx;
DEG_evaluation_context_init(&eval_ctx, resolution);
eval_ctx.ctime = (float)scene->r.cfra + scene->r.subframe;
eval_ctx.view_layer = view_layer;
if (resolution == eModifierMode_Render) {
ParticleSystemModifierData *psmd = psys_get_modifier(object, particlesystem);
float mat[4][4];
unit_m4(mat);
psys_render_set(object, particlesystem, mat, mat, 1, 1, 0.f);
psmd->flag &= ~eParticleSystemFlag_psys_updated;
particle_system_update(&eval_ctx, scene, object, particlesystem, true);
}
else {
ParticleSystemModifierData *psmd = psys_get_modifier(object, particlesystem);
if (particlesystem->renderdata) {
psys_render_restore(object, particlesystem);
}
psmd->flag &= ~eParticleSystemFlag_psys_updated;
particle_system_update(&eval_ctx, scene, object, particlesystem, false);
}
}
static void particle_recalc(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr, short flag)
{
if (ptr->type == &RNA_ParticleSystem) {
@ -2566,33 +2501,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Billboard Velocity Tail", "Scale billboards by velocity");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
/* simplification */
prop = RNA_def_property(srna, "use_simplify", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "simplify_flag", PART_SIMPLIFY_ENABLE);
RNA_def_property_ui_text(prop, "Child Simplification",
"Remove child strands as the object becomes smaller on the screen");
prop = RNA_def_property(srna, "use_simplify_viewport", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "simplify_flag", PART_SIMPLIFY_VIEWPORT);
RNA_def_property_ui_text(prop, "Viewport", "");
prop = RNA_def_property(srna, "simplify_refsize", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "simplify_refsize");
RNA_def_property_range(prop, 1, SHRT_MAX);
RNA_def_property_ui_text(prop, "Reference Size", "Reference size in pixels, after which simplification begins");
prop = RNA_def_property(srna, "simplify_rate", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Rate", "Speed of simplification");
prop = RNA_def_property(srna, "simplify_transition", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Transition", "Transition period for fading out strands");
prop = RNA_def_property(srna, "simplify_viewport", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 0.999f);
RNA_def_property_ui_text(prop, "Rate", "Speed of Simplification");
/* general values */
prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sta"); /*optional if prop names are the same */
@ -3289,12 +3197,6 @@ static void rna_def_particle_system(BlenderRNA *brna)
FunctionRNA *func;
PropertyRNA *parm;
static const EnumPropertyItem resolution_items[] = {
{eModifierMode_Realtime, "PREVIEW", 0, "Preview", "Apply modifier preview settings"},
{eModifierMode_Render, "RENDER", 0, "Render", "Apply modifier render settings"},
{0, NULL, 0, NULL, NULL}
};
srna = RNA_def_struct(brna, "ParticleSystem", NULL);
RNA_def_struct_ui_text(srna, "Particle System", "Particle system in an object");
RNA_def_struct_ui_icon(srna, ICON_PARTICLE_DATA);
@ -3607,14 +3509,6 @@ static void rna_def_particle_system(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_ParticleSystem_path");
/* set viewport or render resolution */
func = RNA_def_function(srna, "set_resolution", "rna_ParticleSystem_set_resolution");
RNA_def_function_ui_description(func, "Set the resolution to use for the number of particles");
RNA_def_pointer(func, "scene", "Scene", "", "Scene");
RNA_def_pointer(func, "view_layer", "ViewLayer", "", "ViewLayer");
RNA_def_pointer(func, "object", "Object", "", "Object");
RNA_def_enum(func, "resolution", resolution_items, 0, "", "Resolution settings to apply");
/* extract cached hair location data */
func = RNA_def_function(srna, "co_hair", "rna_ParticleSystem_co_hair");
RNA_def_function_ui_description(func, "Obtain cache hair data");

View File

@ -1317,10 +1317,10 @@ static int render_new_particle_system(const EvaluationContext *eval_ctx, Render
float strandlen=0.0f, curlen=0.0f;
float hasize, pa_size, r_tilt, r_length;
float pa_time, pa_birthtime, pa_dietime;
float random, simplify[2], pa_co[3];
float random, pa_co[3];
const float cfra= BKE_scene_frame_get(re->scene);
int i, a, k, max_k=0, totpart;
bool do_simplify = false, do_surfacecache = false, use_duplimat = false;
bool do_surfacecache = false, use_duplimat = false;
int totchild=0, step_nbr;
int seed, path_nbr=0, orco1=0, num;
int totface;
@ -1635,8 +1635,6 @@ static int render_new_particle_system(const EvaluationContext *eval_ctx, Render
get_particle_uvco_mcol(part->from, psmd->dm_final, parent->fuv, num, &sd);
}
do_simplify = psys_render_simplify_params(psys, cpa, simplify);
if (strandbuf) {
int orignum = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, cpa->num) : cpa->num;
@ -1669,12 +1667,6 @@ static int render_new_particle_system(const EvaluationContext *eval_ctx, Render
strand->vert= svert;
copy_v3_v3(strand->orco, sd.orco);
if (do_simplify) {
float *ssimplify= RE_strandren_get_simplify(obr, strand, 1);
ssimplify[0]= simplify[0];
ssimplify[1]= simplify[1];
}
if (sd.surfnor) {
float *snor= RE_strandren_get_surfnor(obr, strand, 1);
copy_v3_v3(snor, sd.surfnor);
@ -4663,22 +4655,10 @@ static void add_render_object(const EvaluationContext *eval_ctx, Render *re, Obj
index= (dob)? dob->persistent_id[0]: 0;
/* It seems that we may generate psys->renderdata recursively in some nasty intricated cases of
* several levels of bupliobject (see T51524).
* For now, basic rule is, do not restore psys if it was already in 'render state'.
* Another, more robust solution could be to add some reference counting to that renderdata... */
bool psys_has_renderdata = false;
/* the emitter has to be processed first (render levels of modifiers) */
/* so here we only check if the emitter should be rendered */
if (ob->particlesystem.first) {
show_emitter = (ob->duplicator_visibility_flag & OB_DUPLI_FLAG_RENDER) != 0;
for (psys=ob->particlesystem.first; psys; psys=psys->next) {
if (!(re->r.scemode & R_VIEWPORT_PREVIEW)) {
psys_has_renderdata |= (psys->renderdata != NULL);
psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
}
}
/* if no psys has "show emitter" selected don't render emitter */
if (show_emitter == 0)
@ -4724,9 +4704,6 @@ static void add_render_object(const EvaluationContext *eval_ctx, Render *re, Obj
if (dob)
psys->flag |= PSYS_USE_IMAT;
init_render_object_data(eval_ctx, re, obr, timeoffset);
if (!(re->r.scemode & R_VIEWPORT_PREVIEW) && !psys_has_renderdata) {
psys_render_restore(ob, psys);
}
psys->flag &= ~PSYS_USE_IMAT;
/* only add instance for objects that have not been used for dupli */
@ -4908,51 +4885,6 @@ static int allow_render_dupli_instance(Render *UNUSED(re), DupliObject *dob, Obj
(!(dob->type == OB_DUPLIGROUP) || !dob->animated));
}
static void dupli_render_particle_set(const EvaluationContext *eval_ctx, Render *re, Object *ob,
int timeoffset, int level, int enable)
{
/* ugly function, but we need to set particle systems to their render
* settings before calling object_duplilist, to get render level duplis */
ParticleSystem *psys;
DerivedMesh *dm;
if (re->r.scemode & R_VIEWPORT_PREVIEW)
return;
if (level >= MAX_DUPLI_RECUR)
return;
if (ob->transflag & OB_DUPLIPARTS) {
for (psys=ob->particlesystem.first; psys; psys=psys->next) {
if (ELEM(psys->part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
if (enable)
psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
else
psys_render_restore(ob, psys);
}
}
if (enable) {
/* this is to make sure we get render level duplis in groups:
* the derivedmesh must be created before init_render_mesh,
* since object_duplilist does dupliparticles before that */
dm = mesh_create_derived_render(eval_ctx, re->scene, ob, CD_MASK_RENDER_INTERNAL);
dm->release(dm);
for (psys=ob->particlesystem.first; psys; psys=psys->next)
psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
}
}
if (ob->dup_group == NULL) return;
FOREACH_GROUP_OBJECT_BEGIN(ob->dup_group, object)
{
dupli_render_particle_set(eval_ctx, re, object, timeoffset, level+1, enable);
}
FOREACH_GROUP_OBJECT_END;
}
static int get_vector_viewlayers(Scene *UNUSED(sce))
{
return 0;
@ -5052,12 +4984,8 @@ static void database_init_objects(const EvaluationContext *eval_ctx, Render *re,
/* create list of duplis generated by this object, particle
* system need to have render settings set for dupli particles */
dupli_render_particle_set(eval_ctx, re, ob, timeoffset, 0, 1);
duplilist = object_duplilist(eval_ctx, re->scene, ob);
duplilist_apply_data = duplilist_apply(eval_ctx, ob, NULL, duplilist);
/* postpone 'dupli_render_particle_set', since RE_addRenderInstance reads
* index values from 'dob->persistent_id[0]', referencing 'psys->child' which
* may be smaller once the particle system is restored, see: T45563. */
for (dob= duplilist->first, i = 0; dob; dob= dob->next, ++i) {
DupliExtraData *dob_extra = &duplilist_apply_data->extra[i];
@ -5150,9 +5078,6 @@ static void database_init_objects(const EvaluationContext *eval_ctx, Render *re,
if (re->test_break(re->tbh)) break;
}
/* restore particle system */
dupli_render_particle_set(eval_ctx, re, ob, timeoffset, 0, false);
if (duplilist_apply_data) {
duplilist_restore(duplilist, duplilist_apply_data);
duplilist_free_apply_data(duplilist_apply_data);

View File

@ -174,9 +174,6 @@ static void pointdensity_cache_psys(const EvaluationContext *eval_ctx, Scene *sc
PointDensity *pd,
Object *ob,
ParticleSystem *psys,
float viewmat[4][4],
float winmat[4][4],
int winx, int winy,
const bool use_render_params)
{
DerivedMesh *dm;
@ -198,11 +195,6 @@ static void pointdensity_cache_psys(const EvaluationContext *eval_ctx, Scene *sc
data_used = point_data_used(pd);
/* Just to create a valid rendering context for particles */
if (use_render_params) {
psys_render_set(ob, psys, viewmat, winmat, winx, winy, 0);
}
if (use_render_params) {
dm = mesh_create_derived_render(eval_ctx, scene,
ob,
@ -215,7 +207,6 @@ static void pointdensity_cache_psys(const EvaluationContext *eval_ctx, Scene *sc
}
if (!psys_check_enabled(ob, psys, use_render_params)) {
psys_render_restore(ob, psys);
return;
}
@ -308,10 +299,6 @@ static void pointdensity_cache_psys(const EvaluationContext *eval_ctx, Scene *sc
end_latt_deform(psys->lattice_deform_data);
psys->lattice_deform_data = NULL;
}
if (use_render_params) {
psys_render_restore(ob, psys);
}
}
@ -482,9 +469,6 @@ static void pointdensity_cache_object(const EvaluationContext *eval_ctx, Scene *
static void cache_pointdensity_ex(const EvaluationContext *eval_ctx,
Scene *scene,
PointDensity *pd,
float viewmat[4][4],
float winmat[4][4],
int winx, int winy,
const bool use_render_params)
{
if (pd == NULL) {
@ -514,8 +498,6 @@ static void cache_pointdensity_ex(const EvaluationContext *eval_ctx,
pd,
ob,
psys,
viewmat, winmat,
winx, winy,
use_render_params);
}
else if (pd->source == TEX_PD_OBJECT) {
@ -530,8 +512,6 @@ void cache_pointdensity(const EvaluationContext *eval_ctx, Render *re, PointDens
cache_pointdensity_ex(eval_ctx,
re->scene,
pd,
re->viewmat, re->winmat,
re->winx, re->winy,
true);
}
@ -888,7 +868,6 @@ static void particle_system_minmax(const EvaluationContext *eval_ctx,
Object *object,
ParticleSystem *psys,
float radius,
const bool use_render_params,
float min[3], float max[3])
{
const float size[3] = {radius, radius, radius};
@ -907,9 +886,6 @@ static void particle_system_minmax(const EvaluationContext *eval_ctx,
}
unit_m4(mat);
if (use_render_params) {
psys_render_set(object, psys, mat, mat, 1, 1, 0);
}
sim.eval_ctx = eval_ctx;
sim.scene = scene;
@ -939,26 +915,20 @@ static void particle_system_minmax(const EvaluationContext *eval_ctx,
end_latt_deform(psys->lattice_deform_data);
psys->lattice_deform_data = NULL;
}
if (use_render_params) {
psys_render_restore(object, psys);
}
}
void RE_point_density_cache(
const struct EvaluationContext *eval_ctx,
PointDensity *pd)
{
float mat[4][4];
const bool use_render_params = (eval_ctx->mode == DAG_EVAL_RENDER);
Depsgraph *depsgraph = eval_ctx->depsgraph;
Scene *scene = DEG_get_evaluated_scene(depsgraph);
/* Same matricies/resolution as dupli_render_particle_set(). */
unit_m4(mat);
BLI_mutex_lock(&sample_mutex);
cache_pointdensity_ex(eval_ctx, scene, pd, mat, mat, 1, 1, use_render_params);
cache_pointdensity_ex(eval_ctx, scene, pd, use_render_params);
BLI_mutex_unlock(&sample_mutex);
}
@ -967,7 +937,6 @@ void RE_point_density_minmax(
struct PointDensity *pd,
float r_min[3], float r_max[3])
{
const bool use_render_params = (eval_ctx->mode == DAG_EVAL_RENDER);
Depsgraph *depsgraph = eval_ctx->depsgraph;
Scene *scene = DEG_get_evaluated_scene(depsgraph);
Object *object = pd->object;
@ -996,7 +965,6 @@ void RE_point_density_minmax(
object,
psys,
pd->radius,
use_render_params,
r_min, r_max);
}
else {