diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2017-08-07 15:06:02 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2017-08-07 15:06:02 +0300 |
commit | 41e8bd9337563fc835300513e2273ad71696a619 (patch) | |
tree | 5bd64ec925725b8bb5a16488d460d3808e34180a /source | |
parent | 77802b21a68e544feb92286de27e063cf09bfa12 (diff) | |
parent | 459365443f62d2f8e8718c1d1b0fbaafd6d765de (diff) |
Merge branch 'blender2.8' of git.blender.org:blender into strand_editmode
Diffstat (limited to 'source')
509 files changed, 11009 insertions, 4626 deletions
diff --git a/source/blender/alembic/intern/abc_camera.cc b/source/blender/alembic/intern/abc_camera.cc index 16416205983..aa5d77ce4ec 100644 --- a/source/blender/alembic/intern/abc_camera.cc +++ b/source/blender/alembic/intern/abc_camera.cc @@ -49,12 +49,13 @@ using Alembic::AbcGeom::kWrapExisting; /* ************************************************************************** */ -AbcCameraWriter::AbcCameraWriter(Scene *scene, +AbcCameraWriter::AbcCameraWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, ExportSettings &settings) - : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, scene, ob, time_sampling, settings, parent) { OCamera camera(parent->alembicXform(), m_name, m_time_sampling); m_camera_schema = camera.getSchema(); diff --git a/source/blender/alembic/intern/abc_camera.h b/source/blender/alembic/intern/abc_camera.h index 16c5cccd5ea..772b7a6aec6 100644 --- a/source/blender/alembic/intern/abc_camera.h +++ b/source/blender/alembic/intern/abc_camera.h @@ -35,7 +35,8 @@ class AbcCameraWriter : public AbcObjectWriter { Alembic::AbcGeom::OFloatProperty m_eye_separation; public: - AbcCameraWriter(Scene *scene, + AbcCameraWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc index f73fe957fea..5328c471093 100644 --- a/source/blender/alembic/intern/abc_curves.cc +++ b/source/blender/alembic/intern/abc_curves.cc @@ -71,12 +71,13 @@ using Alembic::AbcGeom::OV2fGeomParam; /* ************************************************************************** */ -AbcCurveWriter::AbcCurveWriter(Scene *scene, +AbcCurveWriter::AbcCurveWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, ExportSettings &settings) - : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, scene, ob, time_sampling, settings, parent) { OCurves curves(parent->alembicXform(), m_name, m_time_sampling); m_schema = curves.getSchema(); diff --git a/source/blender/alembic/intern/abc_curves.h b/source/blender/alembic/intern/abc_curves.h index a9231f947b2..73cc8b35e27 100644 --- a/source/blender/alembic/intern/abc_curves.h +++ b/source/blender/alembic/intern/abc_curves.h @@ -36,7 +36,8 @@ class AbcCurveWriter : public AbcObjectWriter { Alembic::AbcGeom::OCurvesSchema::Sample m_sample; public: - AbcCurveWriter(Scene *scene, + AbcCurveWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index 680913e45ea..df2bc52aa2c 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -163,11 +163,12 @@ static bool export_object(const ExportSettings * const settings, const Base * co /* ************************************************************************** */ -AbcExporter::AbcExporter(Scene *scene, const char *filename, ExportSettings &settings) +AbcExporter::AbcExporter(EvaluationContext *eval_ctx, Scene *scene, const char *filename, ExportSettings &settings) : m_settings(settings) , m_filename(filename) , m_trans_sampling_index(0) , m_shape_sampling_index(0) + , m_eval_ctx(eval_ctx) , m_scene(scene) , m_writer(NULL) {} @@ -383,7 +384,7 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Base *ob_base, O } if (object_type_is_exportable(ob)) { - createTransformWriter(ob, parent, dupliObParent); + createTransformWriter(eval_ctx, ob, parent, dupliObParent); } ListBase *lb = object_duplilist(eval_ctx, m_scene, ob); @@ -415,7 +416,7 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Base *ob_base, O free_object_duplilist(lb); } -AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupliObParent) +AbcTransformWriter * AbcExporter::createTransformWriter(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent) { /* An object should not be its own parent, or we'll get infinite loops. */ BLI_assert(ob != parent); @@ -450,29 +451,29 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *pare * return the parent's AbcTransformWriter pointer. */ if (parent->parent) { if (parent == dupliObParent) { - parent_writer = createTransformWriter(parent, parent->parent, NULL); + parent_writer = createTransformWriter(eval_ctx, parent, parent->parent, NULL); } else { - parent_writer = createTransformWriter(parent, parent->parent, dupliObParent); + parent_writer = createTransformWriter(eval_ctx, parent, parent->parent, dupliObParent); } } else if (parent == dupliObParent) { if (dupliObParent->parent == NULL) { - parent_writer = createTransformWriter(parent, NULL, NULL); + parent_writer = createTransformWriter(eval_ctx, parent, NULL, NULL); } else { - parent_writer = createTransformWriter(parent, dupliObParent->parent, dupliObParent->parent); + parent_writer = createTransformWriter(eval_ctx, parent, dupliObParent->parent, dupliObParent->parent); } } else { - parent_writer = createTransformWriter(parent, dupliObParent, dupliObParent); + parent_writer = createTransformWriter(eval_ctx, parent, dupliObParent, dupliObParent); } BLI_assert(parent_writer); alembic_parent = parent_writer->alembicXform(); } - my_writer = new AbcTransformWriter(ob, alembic_parent, parent_writer, + my_writer = new AbcTransformWriter(eval_ctx, ob, alembic_parent, parent_writer, m_trans_sampling_index, m_settings); /* When flattening, the matrix of the dupliobject has to be added. */ @@ -540,10 +541,10 @@ void AbcExporter::createParticleSystemsWriters(Object *ob, AbcTransformWriter *x if (m_settings.export_hair && psys->part->type == PART_HAIR) { m_settings.export_child_hairs = true; - m_shapes.push_back(new AbcHairWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys)); + m_shapes.push_back(new AbcHairWriter(m_eval_ctx, m_scene, ob, xform, m_shape_sampling_index, m_settings, psys)); } else if (m_settings.export_particles && psys->part->type == PART_EMITTER) { - m_shapes.push_back(new AbcPointsWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys)); + m_shapes.push_back(new AbcPointsWriter(m_eval_ctx, m_scene, ob, xform, m_shape_sampling_index, m_settings, psys)); } } } @@ -583,7 +584,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent) return; } - m_shapes.push_back(new AbcMeshWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings)); + m_shapes.push_back(new AbcMeshWriter(m_eval_ctx, m_scene, ob, xform, m_shape_sampling_index, m_settings)); break; } case OB_SURF: @@ -594,7 +595,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent) return; } - m_shapes.push_back(new AbcNurbsWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings)); + m_shapes.push_back(new AbcNurbsWriter(m_eval_ctx, m_scene, ob, xform, m_shape_sampling_index, m_settings)); break; } case OB_CURVE: @@ -605,7 +606,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent) return; } - m_shapes.push_back(new AbcCurveWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings)); + m_shapes.push_back(new AbcCurveWriter(m_eval_ctx, m_scene, ob, xform, m_shape_sampling_index, m_settings)); break; } case OB_CAMERA: @@ -613,7 +614,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent) Camera *cam = static_cast<Camera *>(ob->data); if (cam->type == CAM_PERSP) { - m_shapes.push_back(new AbcCameraWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings)); + m_shapes.push_back(new AbcCameraWriter(m_eval_ctx, m_scene, ob, xform, m_shape_sampling_index, m_settings)); } break; diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h index 15158a9ef51..9c5fb69234c 100644 --- a/source/blender/alembic/intern/abc_exporter.h +++ b/source/blender/alembic/intern/abc_exporter.h @@ -90,6 +90,7 @@ class AbcExporter { unsigned int m_trans_sampling_index, m_shape_sampling_index; + EvaluationContext *m_eval_ctx; Scene *m_scene; ArchiveWriter *m_writer; @@ -101,7 +102,7 @@ class AbcExporter { std::vector<AbcObjectWriter *> m_shapes; public: - AbcExporter(Scene *scene, const char *filename, ExportSettings &settings); + AbcExporter(EvaluationContext *eval_ctx, Scene *scene, const char *filename, ExportSettings &settings); ~AbcExporter(); void operator()(Main *bmain, float &progress, bool &was_canceled); @@ -116,7 +117,7 @@ private: Alembic::Abc::TimeSamplingPtr createTimeSampling(double step); void createTransformWritersHierarchy(EvaluationContext *eval_ctx); - AbcTransformWriter * createTransformWriter(Object *ob, Object *parent, Object *dupliObParent); + AbcTransformWriter * createTransformWriter(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent); void exploreTransform(EvaluationContext *eval_ctx, Base *ob_base, Object *parent, Object *dupliObParent); void exploreObject(EvaluationContext *eval_ctx, Base *ob_base, Object *dupliObParent); void createShapeWriters(EvaluationContext *eval_ctx); diff --git a/source/blender/alembic/intern/abc_hair.cc b/source/blender/alembic/intern/abc_hair.cc index 8f8ed2019d5..2579aa3cc36 100644 --- a/source/blender/alembic/intern/abc_hair.cc +++ b/source/blender/alembic/intern/abc_hair.cc @@ -49,13 +49,14 @@ using Alembic::AbcGeom::OV2fGeomParam; /* ************************************************************************** */ -AbcHairWriter::AbcHairWriter(Scene *scene, +AbcHairWriter::AbcHairWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, ExportSettings &settings, ParticleSystem *psys) - : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, scene, ob, time_sampling, settings, parent) , m_uv_warning_shown(false) { m_psys = psys; @@ -76,7 +77,7 @@ void AbcHairWriter::do_write() return; } - DerivedMesh *dm = mesh_create_derived_render(m_scene, m_object, CD_MASK_MESH); + DerivedMesh *dm = mesh_create_derived_render(m_eval_ctx, m_scene, m_object, CD_MASK_MESH); DM_ensure_tessface(dm); std::vector<Imath::V3f> verts; diff --git a/source/blender/alembic/intern/abc_hair.h b/source/blender/alembic/intern/abc_hair.h index 61f5fe361f8..8190c449205 100644 --- a/source/blender/alembic/intern/abc_hair.h +++ b/source/blender/alembic/intern/abc_hair.h @@ -40,7 +40,8 @@ class AbcHairWriter : public AbcObjectWriter { bool m_uv_warning_shown; public: - AbcHairWriter(Scene *scene, + AbcHairWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index bc62db5702c..25cf5f49b14 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -286,12 +286,13 @@ static ModifierData *get_liquid_sim_modifier(Scene *scene, Object *ob) /* ************************************************************************** */ -AbcMeshWriter::AbcMeshWriter(Scene *scene, +AbcMeshWriter::AbcMeshWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, ExportSettings &settings) - : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, scene, ob, time_sampling, settings, parent) { m_is_animated = isAnimated(); m_subsurf_mod = NULL; @@ -519,7 +520,7 @@ DerivedMesh *AbcMeshWriter::getFinalMesh() m_subsurf_mod->mode |= eModifierMode_DisableTemporary; } - DerivedMesh *dm = mesh_create_derived_render(m_scene, m_object, CD_MASK_MESH); + DerivedMesh *dm = mesh_create_derived_render(m_eval_ctx, m_scene, m_object, CD_MASK_MESH); if (m_subsurf_mod) { m_subsurf_mod->mode &= ~eModifierMode_DisableTemporary; diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h index 6bf1dde3d1d..941407d2208 100644 --- a/source/blender/alembic/intern/abc_mesh.h +++ b/source/blender/alembic/intern/abc_mesh.h @@ -50,7 +50,8 @@ class AbcMeshWriter : public AbcObjectWriter { bool m_is_subd; public: - AbcMeshWriter(Scene *scene, + AbcMeshWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, diff --git a/source/blender/alembic/intern/abc_nurbs.cc b/source/blender/alembic/intern/abc_nurbs.cc index eaef06fd6d1..0532191a28d 100644 --- a/source/blender/alembic/intern/abc_nurbs.cc +++ b/source/blender/alembic/intern/abc_nurbs.cc @@ -60,12 +60,13 @@ using Alembic::AbcGeom::ONuPatchSchema; /* ************************************************************************** */ -AbcNurbsWriter::AbcNurbsWriter(Scene *scene, +AbcNurbsWriter::AbcNurbsWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, ExportSettings &settings) - : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, scene, ob, time_sampling, settings, parent) { m_is_animated = isAnimated(); diff --git a/source/blender/alembic/intern/abc_nurbs.h b/source/blender/alembic/intern/abc_nurbs.h index abe460a8988..3d20c5c60bb 100644 --- a/source/blender/alembic/intern/abc_nurbs.h +++ b/source/blender/alembic/intern/abc_nurbs.h @@ -32,7 +32,8 @@ class AbcNurbsWriter : public AbcObjectWriter { bool m_is_animated; public: - AbcNurbsWriter(Scene *scene, + AbcNurbsWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc index 9f8960c827f..98ebcf6debb 100644 --- a/source/blender/alembic/intern/abc_object.cc +++ b/source/blender/alembic/intern/abc_object.cc @@ -58,13 +58,15 @@ using Alembic::AbcGeom::OStringProperty; /* ************************************************************************** */ -AbcObjectWriter::AbcObjectWriter(Scene *scene, +AbcObjectWriter::AbcObjectWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, uint32_t time_sampling, ExportSettings &settings, AbcObjectWriter *parent) : m_object(ob) , m_settings(settings) + , m_eval_ctx(eval_ctx) , m_scene(scene) , m_time_sampling(time_sampling) , m_first_frame(true) diff --git a/source/blender/alembic/intern/abc_object.h b/source/blender/alembic/intern/abc_object.h index 852ef451f23..6aa6224f8d5 100644 --- a/source/blender/alembic/intern/abc_object.h +++ b/source/blender/alembic/intern/abc_object.h @@ -44,6 +44,7 @@ protected: Object *m_object; ExportSettings &m_settings; + EvaluationContext *m_eval_ctx; Scene *m_scene; uint32_t m_time_sampling; @@ -56,7 +57,8 @@ protected: std::string m_name; public: - AbcObjectWriter(Scene *scene, + AbcObjectWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, uint32_t time_sampling, ExportSettings &settings, diff --git a/source/blender/alembic/intern/abc_points.cc b/source/blender/alembic/intern/abc_points.cc index 80567cd6bf0..feb2eff5b9d 100644 --- a/source/blender/alembic/intern/abc_points.cc +++ b/source/blender/alembic/intern/abc_points.cc @@ -58,13 +58,14 @@ using Alembic::AbcGeom::OPointsSchema; /* ************************************************************************** */ -AbcPointsWriter::AbcPointsWriter(Scene *scene, +AbcPointsWriter::AbcPointsWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, ExportSettings &settings, ParticleSystem *psys) - : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, scene, ob, time_sampling, settings, parent) { m_psys = psys; @@ -86,6 +87,7 @@ void AbcPointsWriter::do_write() ParticleKey state; ParticleSimulationData sim; + sim.eval_ctx = m_eval_ctx; sim.scene = m_scene; sim.ob = m_object; sim.psys = m_psys; diff --git a/source/blender/alembic/intern/abc_points.h b/source/blender/alembic/intern/abc_points.h index 369a802d763..b60f1997aa8 100644 --- a/source/blender/alembic/intern/abc_points.h +++ b/source/blender/alembic/intern/abc_points.h @@ -38,7 +38,8 @@ class AbcPointsWriter : public AbcObjectWriter { ParticleSystem *m_psys; public: - AbcPointsWriter(Scene *scene, + AbcPointsWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, diff --git a/source/blender/alembic/intern/abc_transform.cc b/source/blender/alembic/intern/abc_transform.cc index 5392387663f..0a1480e62b0 100644 --- a/source/blender/alembic/intern/abc_transform.cc +++ b/source/blender/alembic/intern/abc_transform.cc @@ -57,12 +57,13 @@ static bool has_parent_camera(Object *ob) /* ************************************************************************** */ -AbcTransformWriter::AbcTransformWriter(Object *ob, +AbcTransformWriter::AbcTransformWriter(EvaluationContext *eval_ctx, + Object *ob, const OObject &abc_parent, AbcTransformWriter *parent, unsigned int time_sampling, ExportSettings &settings) - : AbcObjectWriter(NULL, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, NULL, ob, time_sampling, settings, parent) , m_proxy_from(NULL) { m_is_animated = hasAnimation(m_object); diff --git a/source/blender/alembic/intern/abc_transform.h b/source/blender/alembic/intern/abc_transform.h index 753a4247e9f..e82765cb169 100644 --- a/source/blender/alembic/intern/abc_transform.h +++ b/source/blender/alembic/intern/abc_transform.h @@ -44,7 +44,8 @@ public: Object *m_proxy_from; public: - AbcTransformWriter(Object *ob, + AbcTransformWriter(EvaluationContext *eval_ctx, + Object *ob, const Alembic::AbcGeom::OObject &abc_parent, AbcTransformWriter *parent, unsigned int time_sampling, diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc index 692fc203706..97a269b8fc0 100644 --- a/source/blender/alembic/intern/alembic_capi.cc +++ b/source/blender/alembic/intern/alembic_capi.cc @@ -230,6 +230,7 @@ static void find_iobject(const IObject &object, IObject &ret, } struct ExportJobData { + EvaluationContext eval_ctx; Scene *scene; Main *bmain; @@ -262,7 +263,7 @@ static void export_startjob(void *customdata, short *stop, short *do_update, flo try { Scene *scene = data->scene; - AbcExporter exporter(scene, data->filename, data->settings); + AbcExporter exporter(&data->eval_ctx, scene, data->filename, data->settings); const int orig_frame = CFRA; @@ -310,6 +311,9 @@ bool ABC_export( bool as_background_job) { ExportJobData *job = static_cast<ExportJobData *>(MEM_mallocN(sizeof(ExportJobData), "ExportJobData")); + + CTX_data_eval_ctx(C, &job->eval_ctx); + job->scene = scene; job->bmain = CTX_data_main(C); job->export_ok = false; diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 78c2efcc8a2..63b5dc68875 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -98,6 +98,7 @@ struct ColorBand; struct GPUVertexAttribs; struct GPUDrawObject; struct PBVH; +struct EvaluationContext; /* number of sub-elements each mesh element has (for interpolation) */ #define SUB_ELEMS_VERT 0 @@ -658,56 +659,56 @@ void mesh_get_mapped_verts_coords(DerivedMesh *dm, float (*r_cos)[3], const int /* */ DerivedMesh *mesh_get_derived_final( - struct Scene *scene, struct Object *ob, - CustomDataMask dataMask); + struct EvaluationContext *eval_ctx, struct Scene *scene, + struct Object *ob, CustomDataMask dataMask); DerivedMesh *mesh_get_derived_deform( - struct Scene *scene, struct Object *ob, - CustomDataMask dataMask); + struct EvaluationContext *eval_ctx, struct Scene *scene, + struct Object *ob, CustomDataMask dataMask); DerivedMesh *mesh_create_derived_for_modifier( - struct Scene *scene, struct Object *ob, + struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ModifierData *md, int build_shapekey_layers); DerivedMesh *mesh_create_derived_render( - struct Scene *scene, struct Object *ob, - CustomDataMask dataMask); + struct EvaluationContext *eval_ctx, struct Scene *scene, + struct Object *ob, CustomDataMask dataMask); DerivedMesh *getEditDerivedBMesh( struct BMEditMesh *em, struct Object *ob, CustomDataMask data_mask, float (*vertexCos)[3]); DerivedMesh *mesh_create_derived_index_render( - struct Scene *scene, struct Object *ob, - CustomDataMask dataMask, int index); + struct EvaluationContext *eval_ctx, struct Scene *scene, + struct Object *ob, CustomDataMask dataMask, int index); /* same as above but wont use render settings */ DerivedMesh *mesh_create_derived(struct Mesh *me, float (*vertCos)[3]); DerivedMesh *mesh_create_derived_view( - struct Scene *scene, struct Object *ob, - CustomDataMask dataMask); + struct EvaluationContext *eval_ctx, struct Scene *scene, + struct Object *ob, CustomDataMask dataMask); DerivedMesh *mesh_create_derived_no_deform( - struct Scene *scene, struct Object *ob, - float (*vertCos)[3], + struct EvaluationContext *eval_ctx, struct Scene *scene, + struct Object *ob, float (*vertCos)[3], CustomDataMask dataMask); DerivedMesh *mesh_create_derived_no_deform_render( - struct Scene *scene, struct Object *ob, - float (*vertCos)[3], + struct EvaluationContext *eval_ctx, struct Scene *scene, + struct Object *ob, float (*vertCos)[3], CustomDataMask dataMask); /* for gameengine */ DerivedMesh *mesh_create_derived_no_virtual( - struct Scene *scene, struct Object *ob, float (*vertCos)[3], - CustomDataMask dataMask); + struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, + float (*vertCos)[3], CustomDataMask dataMask); DerivedMesh *mesh_create_derived_physics( - struct Scene *scene, struct Object *ob, float (*vertCos)[3], - CustomDataMask dataMask); + struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, + float (*vertCos)[3], CustomDataMask dataMask); DerivedMesh *editbmesh_get_derived_base( struct Object *ob, struct BMEditMesh *em, CustomDataMask data_mask); DerivedMesh *editbmesh_get_derived_cage( - struct Scene *scene, struct Object *, + struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *, struct BMEditMesh *em, CustomDataMask dataMask); DerivedMesh *editbmesh_get_derived_cage_and_final( - struct Scene *scene, struct Object *, + struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *, struct BMEditMesh *em, CustomDataMask dataMask, DerivedMesh **r_final); @@ -716,7 +717,7 @@ DerivedMesh *object_get_derived_final(struct Object *ob, const bool for_render); float (*editbmesh_get_vertex_cos(struct BMEditMesh *em, int *r_numVerts))[3]; bool editbmesh_modifier_is_enabled(struct Scene *scene, struct ModifierData *md, DerivedMesh *dm); void makeDerivedMesh( - struct Scene *scene, struct Object *ob, struct BMEditMesh *em, + struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct BMEditMesh *em, CustomDataMask dataMask, const bool build_shapekey_layers); void weight_to_rgb(float r_rgb[3], const float weight); diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index 584f0da323a..ef8a1c7e417 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -41,6 +41,7 @@ struct bAnimVizSettings; struct bMotionPath; struct bPoseChannel; struct ReportList; +struct bContext; /* ---------------------------------------------------- */ /* Animation Visualization */ @@ -53,7 +54,7 @@ void animviz_free_motionpath(struct bMotionPath *mpath); struct bMotionPath *animviz_verify_motionpaths(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan); void animviz_get_object_motionpaths(struct Object *ob, ListBase *targets); -void animviz_calc_motionpaths(struct Scene *scene, ListBase *targets); +void animviz_calc_motionpaths(struct bContext *C, struct Scene *scene, ListBase *targets); /* ---------------------------------------------------- */ /* Curve Paths */ @@ -80,7 +81,7 @@ typedef struct DupliApplyData { DupliExtraData *extra; } DupliApplyData; -DupliApplyData *duplilist_apply(struct Object *ob, struct Scene *scene, struct ListBase *duplilist); +DupliApplyData *duplilist_apply(struct EvaluationContext *eval_ctx, struct Object *ob, struct Scene *scene, struct ListBase *duplilist); void duplilist_restore(struct ListBase *duplilist, DupliApplyData *apply_data); void duplilist_free_apply_data(DupliApplyData *apply_data); diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index fa3bf0e79c9..41783700bf6 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -35,6 +35,7 @@ struct bPose; struct Bone; +struct EvaluationContext; struct GHash; struct Main; struct bArmature; @@ -98,8 +99,8 @@ void BKE_armature_where_is(struct bArmature *arm); void BKE_armature_where_is_bone(struct Bone *bone, struct Bone *prevbone, const bool use_recursion); void BKE_pose_clear_pointers(struct bPose *pose); void BKE_pose_rebuild(struct Object *ob, struct bArmature *arm); -void BKE_pose_where_is(struct Scene *scene, struct Object *ob); -void BKE_pose_where_is_bone(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra); +void BKE_pose_where_is(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); +void BKE_pose_where_is_bone(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra); void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan); /* get_objectspace_bone_matrix has to be removed still */ @@ -116,7 +117,7 @@ void BKE_armature_loc_pose_to_bone(struct bPoseChannel *pchan, const float inloc void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]); void BKE_armature_mat_pose_to_delta(float delta_mat[4][4], float pose_mat[4][4], float arm_mat[4][4]); -void BKE_armature_mat_pose_to_bone_ex(struct Object *ob, struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]); +void BKE_armature_mat_pose_to_bone_ex(struct EvaluationContext *eval_ctx, struct Object *ob, struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]); void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[3][3], bool use_compat); void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[4][4], bool use_comat); @@ -154,7 +155,6 @@ void b_bone_spline_setup(struct bPoseChannel *pchan, int rest, Mat4 result_array struct bKinematicConstraint; struct bPose; struct bSplineIKConstraint; -struct EvaluationContext; struct bPoseChannel *BKE_armature_ik_solver_find_root( struct bPoseChannel *pchan, @@ -164,7 +164,7 @@ struct bPoseChannel *BKE_armature_splineik_solver_find_root( struct bSplineIKConstraint *data); void BKE_pose_splineik_init_tree(struct Scene *scene, struct Object *ob, float ctime); -void BKE_splineik_execute_tree(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan_root, float ctime); +void BKE_splineik_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan_root, float ctime); void BKE_pose_eval_init(struct EvaluationContext *eval_ctx, struct Scene *scene, diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 6c517bd02df..67723209e75 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -41,6 +41,7 @@ struct MFace; struct DerivedMesh; struct ClothModifierData; struct CollisionModifierData; +struct EvaluationContext; #define DO_INLINE MALWAYS_INLINE @@ -226,7 +227,7 @@ void cloth_free_contacts(ColliderContacts *collider_contacts, int totcolliders); void cloth_free_modifier_extern (struct ClothModifierData *clmd ); void cloth_free_modifier (struct ClothModifierData *clmd ); void cloth_init (struct ClothModifierData *clmd ); -void clothModifier_do (struct ClothModifierData *clmd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3]); +void clothModifier_do (struct ClothModifierData *clmd, struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3]); int cloth_uses_vgroup(struct ClothModifierData *clmd); diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h index 047d1787f76..6490418edbe 100644 --- a/source/blender/blenkernel/BKE_constraint.h +++ b/source/blender/blenkernel/BKE_constraint.h @@ -40,6 +40,7 @@ struct ListBase; struct Object; struct Scene; struct bPoseChannel; +struct EvaluationContext; /* ---------------------------------------------------------------------------- */ #ifdef __cplusplus @@ -102,7 +103,7 @@ typedef struct bConstraintTypeInfo { /* evaluation */ /* set the ct->matrix for the given constraint target (at the given ctime) */ - void (*get_target_matrix)(struct bConstraint *con, struct bConstraintOb *cob, struct bConstraintTarget *ct, float ctime); + void (*get_target_matrix)(struct EvaluationContext *eval_ctx, struct bConstraint *con, struct bConstraintOb *cob, struct bConstraintTarget *ct, float ctime); /* evaluate the constraint for the given time */ void (*evaluate_constraint)(struct bConstraint *con, struct bConstraintOb *cob, struct ListBase *targets); } bConstraintTypeInfo; @@ -146,9 +147,10 @@ void BKE_constraints_clear_evalob(struct bConstraintOb *cob); void BKE_constraint_mat_convertspace( struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to, const bool keep_scale); -void BKE_constraint_target_matrix_get(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime); -void BKE_constraint_targets_for_solving_get(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime); -void BKE_constraints_solve(struct ListBase *conlist, struct bConstraintOb *cob, float ctime); +void BKE_constraint_target_matrix_get(struct EvaluationContext *eval_ctx, struct Scene *scene, struct bConstraint *con, + int n, short ownertype, void *ownerdata, float mat[4][4], float ctime); +void BKE_constraint_targets_for_solving_get(struct EvaluationContext *eval_ctx, struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime); +void BKE_constraints_solve(struct EvaluationContext *eval_ctx, struct ListBase *conlist, struct bConstraintOb *cob, float ctime); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 63e83aaa967..9d47ac470ea 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -73,6 +73,7 @@ struct SpaceText; struct SpaceImage; struct SpaceClip; struct ID; +struct EvaluationContext; /* Structs */ @@ -153,6 +154,7 @@ struct SpaceLink *CTX_wm_space_data(const bContext *C); struct ARegion *CTX_wm_region(const bContext *C); void *CTX_wm_region_data(const bContext *C); struct ARegion *CTX_wm_menu(const bContext *C); +struct wmManipulatorGroup *CTX_wm_manipulator_group(const bContext *C); struct ReportList *CTX_wm_reports(const bContext *C); struct View3D *CTX_wm_view3d(const bContext *C); @@ -180,6 +182,7 @@ void CTX_wm_screen_set(bContext *C, struct bScreen *screen); /* to be removed */ void CTX_wm_area_set(bContext *C, struct ScrArea *sa); void CTX_wm_region_set(bContext *C, struct ARegion *region); void CTX_wm_menu_set(bContext *C, struct ARegion *menu); +void CTX_wm_manipulator_group_set(bContext *C, struct wmManipulatorGroup *mgroup); const char *CTX_wm_operator_poll_msg_get(struct bContext *C); void CTX_wm_operator_poll_msg_set(struct bContext *C, const char *msg); @@ -309,6 +312,8 @@ int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list); struct Depsgraph *CTX_data_depsgraph(const bContext *C); +void CTX_data_eval_ctx(const bContext *C, struct EvaluationContext *eval_ctx); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_crazyspace.h b/source/blender/blenkernel/BKE_crazyspace.h index ee6c5c57678..4fe52370f47 100644 --- a/source/blender/blenkernel/BKE_crazyspace.h +++ b/source/blender/blenkernel/BKE_crazyspace.h @@ -38,23 +38,24 @@ struct Scene; struct Object; struct BMEditMesh; struct Mesh; +struct EvaluationContext; /* crazyspace.c */ float (*BKE_crazyspace_get_mapped_editverts( - struct Scene *scene, struct Object *obedit))[3]; + struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *obedit))[3]; void BKE_crazyspace_set_quats_editmesh( struct BMEditMesh *em, float (*origcos)[3], float (*mappedcos)[3], float (*quats)[4], const bool use_select); void BKE_crazyspace_set_quats_mesh( struct Mesh *me, float (*origcos)[3], float (*mappedcos)[3], float (*quats)[4]); int BKE_crazyspace_get_first_deform_matrices_editbmesh( - struct Scene *, struct Object *, struct BMEditMesh *em, + struct EvaluationContext *eval_ctx, struct Scene *, struct Object *, struct BMEditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3]); int BKE_sculpt_get_first_deform_matrices( - struct Scene *scene, struct Object *ob, + struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]); void BKE_crazyspace_build_sculpt( - struct Scene *scene, struct Object *ob, + struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]); #ifdef __cplusplus diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 5a65646efe0..501a623acea 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -36,6 +36,7 @@ struct BezTriple; struct Curve; struct EditNurb; +struct EvaluationContext; struct GHash; struct ListBase; struct Main; @@ -121,12 +122,12 @@ void BKE_curve_editNurb_keyIndex_free(struct GHash **keyindex); void BKE_curve_editNurb_free(struct Curve *cu); struct ListBase *BKE_curve_editNurbs_get(struct Curve *cu); -float *BKE_curve_make_orco(struct Scene *scene, struct Object *ob, int *r_numVerts); +float *BKE_curve_make_orco(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, int *r_numVerts); float *BKE_curve_surf_make_orco(struct Object *ob); void BKE_curve_bevelList_free(struct ListBase *bev); void BKE_curve_bevelList_make(struct Object *ob, struct ListBase *nurbs, bool for_render); -void BKE_curve_bevel_make(struct Scene *scene, struct Object *ob, struct ListBase *disp, +void BKE_curve_bevel_make(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *disp, const bool for_render, const bool use_render_resolution); void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride); @@ -212,8 +213,6 @@ void BKE_nurb_handles_test(struct Nurb *nu, const bool use_handles); /* **** Depsgraph evaluation **** */ -struct EvaluationContext; - void BKE_curve_eval_geometry(struct EvaluationContext *eval_ctx, struct Curve *curve); diff --git a/source/blender/blenkernel/BKE_data_transfer.h b/source/blender/blenkernel/BKE_data_transfer.h index 2ee9d8d2408..497319819de 100644 --- a/source/blender/blenkernel/BKE_data_transfer.h +++ b/source/blender/blenkernel/BKE_data_transfer.h @@ -42,6 +42,7 @@ struct Object; struct Scene; struct SpaceTransform; struct ReportList; +struct EvaluationContext; /* Warning, those def are stored in files (TransferData modifier), *DO NOT* modify those values. */ enum { @@ -129,11 +130,12 @@ enum { }; void BKE_object_data_transfer_layout( - struct Scene *scene, struct Object *ob_src, struct Object *ob_dst, const int data_types, const bool use_delete, + struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob_src, + struct Object *ob_dst, const int data_types, const bool use_delete, const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX]); bool BKE_object_data_transfer_mesh( - struct Scene *scene, + struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob_src, struct Object *ob_dst, const int data_types, const bool use_create, const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode, struct SpaceTransform *space_transform, const bool auto_transform, @@ -142,7 +144,7 @@ bool BKE_object_data_transfer_mesh( const int mix_mode, const float mix_factor, const char *vgroup_name, const bool invert_vgroup, struct ReportList *reports); bool BKE_object_data_transfer_dm( - struct Scene *scene, + struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob_src, struct Object *ob_dst, struct DerivedMesh *dm_dst, const int data_types, bool use_create, const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode, diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 9625f05192a..641abc54216 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -86,22 +86,22 @@ void BKE_displist_count(struct ListBase *lb, int *totvert, int *totface, int *to void BKE_displist_free(struct ListBase *lb); bool BKE_displist_has_faces(struct ListBase *lb); -void BKE_displist_make_surf(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct DerivedMesh **r_dm_final, - const bool for_render, const bool for_orco, const bool use_render_resolution); -void BKE_displist_make_curveTypes(struct Scene *scene, struct Object *ob, const bool for_orco); -void BKE_displist_make_curveTypes_forRender(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct DerivedMesh **r_dm_final, - const bool for_orco, const bool use_render_resolution); -void BKE_displist_make_curveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase); +void BKE_displist_make_surf(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase, + struct DerivedMesh **r_dm_final, const bool for_render, const bool for_orco, const bool use_render_resolution); +void BKE_displist_make_curveTypes(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, const bool for_orco); +void BKE_displist_make_curveTypes_forRender(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase, + struct DerivedMesh **r_dm_final, const bool for_orco, const bool use_render_resolution); +void BKE_displist_make_curveTypes_forOrco(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase); void BKE_displist_make_mball(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); void BKE_displist_make_mball_forRender(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase); bool BKE_displist_surfindex_get(DispList *dl, int a, int *b, int *p1, int *p2, int *p3, int *p4); void BKE_displist_fill(struct ListBase *dispbase, struct ListBase *to, const float normal_proj[3], const bool flipnormal); -float BKE_displist_calc_taper(struct Scene *scene, struct Object *taperobj, int cur, int tot); +float BKE_displist_calc_taper(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *taperobj, int cur, int tot); /* add Orco layer to the displist object which has got derived mesh and return orco */ -float *BKE_displist_make_orco(struct Scene *scene, struct Object *ob, struct DerivedMesh *dm_final, +float *BKE_displist_make_orco(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm_final, const bool for_render, const bool use_render_resolution); void BKE_displist_minmax(struct ListBase *dispbase, float min[3], float max[3]); diff --git a/source/blender/blenkernel/BKE_dynamicpaint.h b/source/blender/blenkernel/BKE_dynamicpaint.h index b22f5fa7630..1360d0c730f 100644 --- a/source/blender/blenkernel/BKE_dynamicpaint.h +++ b/source/blender/blenkernel/BKE_dynamicpaint.h @@ -29,6 +29,7 @@ struct Scene; struct SceneLayer; +struct EvaluationContext; /* Actual surface point */ typedef struct PaintSurfaceData { @@ -61,8 +62,8 @@ typedef struct PaintWavePoint { short state; } PaintWavePoint; -struct DerivedMesh *dynamicPaint_Modifier_do(struct DynamicPaintModifierData *pmd, struct Scene *scene, - struct SceneLayer *sl, struct Object *ob, struct DerivedMesh *dm); +struct DerivedMesh *dynamicPaint_Modifier_do(struct DynamicPaintModifierData *pmd, struct EvaluationContext *eval_ctx, struct Scene *scene, + struct Object *ob, struct DerivedMesh *dm); void dynamicPaint_Modifier_free(struct DynamicPaintModifierData *pmd); void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct DynamicPaintModifierData *tsmd); @@ -85,7 +86,7 @@ struct DynamicPaintSurface *get_activeSurface(struct DynamicPaintCanvasSettings /* image sequence baking */ int dynamicPaint_createUVSurface(struct Scene *scene, struct DynamicPaintSurface *surface, float *progress, short *do_update); -int dynamicPaint_calculateFrame(struct DynamicPaintSurface *surface, struct Scene *scene, struct SceneLayer *sl, struct Object *cObject, int frame); +int dynamicPaint_calculateFrame(struct DynamicPaintSurface *surface, struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *cObject, int frame); void dynamicPaint_outputSurfaceImage(struct DynamicPaintSurface *surface, char *filename, short output_layer); /* PaintPoint state */ diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h index 9ee1bcf2d37..02ad8777e60 100644 --- a/source/blender/blenkernel/BKE_editmesh.h +++ b/source/blender/blenkernel/BKE_editmesh.h @@ -40,6 +40,7 @@ struct Mesh; struct Scene; struct DerivedMesh; struct MeshStatVis; +struct EvaluationContext; /** * This structure is used for mesh edit-mode. @@ -98,6 +99,6 @@ float (*BKE_editmesh_vertexCos_get_orco(BMEditMesh *em, int *r_numVerts))[3] void BKE_editmesh_statvis_calc(BMEditMesh *em, struct DerivedMesh *dm, const struct MeshStatVis *statvis); -float (*BKE_editmesh_vertexCos_get(struct BMEditMesh *em, struct Scene *scene, int *r_numVerts))[3]; +float (*BKE_editmesh_vertexCos_get(struct EvaluationContext *eval_ctx, struct BMEditMesh *em, struct Scene *scene, int *r_numVerts))[3]; #endif /* __BKE_EDITMESH_H__ */ diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h index aa45132cbe9..383e6d0cb62 100644 --- a/source/blender/blenkernel/BKE_effect.h +++ b/source/blender/blenkernel/BKE_effect.h @@ -44,6 +44,7 @@ struct Group; struct ParticleSimulationData; struct ParticleData; struct ParticleKey; +struct EvaluationContext; struct EffectorWeights *BKE_add_effector_weights(struct Group *group); struct PartDeflect *object_add_collision_fields(int type); @@ -93,6 +94,7 @@ typedef struct EffectorData { typedef struct EffectorCache { struct EffectorCache *next, *prev; + struct EvaluationContext *eval_ctx; struct Scene *scene; struct Object *ob; struct ParticleSystem *psys; @@ -110,9 +112,10 @@ typedef struct EffectorCache { } EffectorCache; void free_partdeflect(struct PartDeflect *pd); -struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights, bool for_simulation); +struct ListBase *pdInitEffectors(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src, + struct EffectorWeights *weights, bool for_simulation); void pdEndEffectors(struct ListBase **effectors); -void pdPrecalculateEffectors(struct ListBase *effectors); +void pdPrecalculateEffectors(struct EvaluationContext *eval_ctx, struct ListBase *effectors); void pdDoEffectors(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *impulse); void pd_point_from_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, struct EffectedPoint *point); diff --git a/source/blender/blenkernel/BKE_fluidsim.h b/source/blender/blenkernel/BKE_fluidsim.h index 6501c968abc..0345382271b 100644 --- a/source/blender/blenkernel/BKE_fluidsim.h +++ b/source/blender/blenkernel/BKE_fluidsim.h @@ -36,10 +36,11 @@ struct Object; struct Scene; struct FluidsimSettings; struct MVert; +struct EvaluationContext; /* old interface */ -void initElbeemMesh(struct Scene *scene, struct Object *ob, +void initElbeemMesh(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, int *numVertices, float **vertices, int *numTriangles, int **triangles, int useGlobalCoords, int modifierIndex); diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 3c66d29e6ac..fe3d388178e 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -43,6 +43,7 @@ struct Scene; struct DerivedMesh; struct BPoint; struct MDeformVert; +struct EvaluationContext; void BKE_lattice_resize(struct Lattice *lt, int u, int v, int w, struct Object *ltOb); void BKE_lattice_init(struct Lattice *lt); @@ -60,10 +61,10 @@ void end_latt_deform(struct LatticeDeformData *lattice_deform_data); bool object_deform_mball(struct Object *ob, struct ListBase *dispbase); void outside_lattice(struct Lattice *lt); -void curve_deform_verts(struct Scene *scene, struct Object *cuOb, struct Object *target, +void curve_deform_verts(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *cuOb, struct Object *target, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts, const char *vgroup, short defaxis); -void curve_deform_vector(struct Scene *scene, struct Object *cuOb, struct Object *target, +void curve_deform_vector(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *cuOb, struct Object *target, float orco[3], float vec[3], float mat[3][3], int no_rot_axis); void lattice_deform_verts(struct Object *laOb, struct Object *target, @@ -76,7 +77,7 @@ void armature_deform_verts(struct Object *armOb, struct Object *target, float (*BKE_lattice_vertexcos_get(struct Object *ob, int *r_numVerts))[3]; void BKE_lattice_vertexcos_apply(struct Object *ob, float (*vertexCos)[3]); -void BKE_lattice_modifiers_calc(struct Scene *scene, struct Object *ob); +void BKE_lattice_modifiers_calc(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); struct MDeformVert *BKE_lattice_deform_verts_get(struct Object *lattice); struct BPoint *BKE_lattice_active_point_get(struct Lattice *lt); diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h index 2e3ff12de13..0a26fe08016 100644 --- a/source/blender/blenkernel/BKE_layer.h +++ b/source/blender/blenkernel/BKE_layer.h @@ -33,13 +33,9 @@ extern "C" { #endif -#define TODO_LAYER_SYNC /* syncing of SceneCollection and LayerCollection trees*/ #define TODO_LAYER_SYNC_FILTER /* syncing of filter_objects across all trees */ #define TODO_LAYER_OVERRIDE /* CollectionOverride */ -#define TODO_LAYER_CONTEXT /* get/set current (context) SceneLayer */ -#define TODO_LAYER_BASE /* BaseLegacy to Base related TODO */ #define TODO_LAYER_OPERATORS /* collection mamanger and property panel operators */ -#define TODO_LAYER_DEPSGRAPH /* placeholder for real Depsgraph fix */ #define TODO_LAYER /* generic todo */ #define ROOT_PROP "root" @@ -65,8 +61,6 @@ struct SceneLayer *BKE_scene_layer_from_workspace_get(const struct WorkSpace *wo struct SceneLayer *BKE_scene_layer_add(struct Scene *scene, const char *name); /* DEPRECATED */ -struct SceneLayer *BKE_scene_layer_context_active_ex_PLACEHOLDER(const struct Main *bmain, const struct Scene *scene); -/* DEPRECATED */ struct SceneLayer *BKE_scene_layer_context_active_PLACEHOLDER(const struct Scene *scene); void BKE_scene_layer_free(struct SceneLayer *sl); diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 85c649bbd3d..14820587200 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -118,6 +118,12 @@ void free_matcopybuf(void); void copy_matcopybuf(struct Material *ma); void paste_matcopybuf(struct Material *ma); +/* Evaluation. */ + +struct EvaluationContext; + +void BKE_material_eval(struct EvaluationContext *eval_ctx, struct Material *material); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 9a94b9513f4..4766f1d37eb 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -35,6 +35,7 @@ struct ID; struct BMeshCreateParams; struct BoundBox; struct EdgeHash; +struct EvaluationContext; struct ListBase; struct LinkNode; struct BLI_Stack; @@ -91,6 +92,9 @@ struct Mesh *BKE_mesh_copy(struct Main *bmain, const struct Mesh *me); void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd); void BKE_mesh_ensure_skin_customdata(struct Mesh *me); +bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me); +bool BKE_mesh_clear_facemap_customdata(struct Mesh *me); + void BKE_mesh_make_local(struct Main *bmain, struct Mesh *me, const bool lib_local); void BKE_mesh_boundbox_calc(struct Mesh *me, float r_loc[3], float r_size[3]); void BKE_mesh_texspace_calc(struct Mesh *me); @@ -114,7 +118,7 @@ void BKE_mesh_from_nurbs_displist( struct Object *ob, struct ListBase *dispbase, const bool use_orco_uv, const char *obdata_name); void BKE_mesh_from_nurbs(struct Object *ob); void BKE_mesh_to_curve_nurblist(struct DerivedMesh *dm, struct ListBase *nurblist, const int edge_users_test); -void BKE_mesh_to_curve(struct Scene *scene, struct Object *ob); +void BKE_mesh_to_curve(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); void BKE_mesh_material_index_remove(struct Mesh *me, short index); void BKE_mesh_material_index_clear(struct Mesh *me); void BKE_mesh_material_remap(struct Mesh *me, const unsigned int *remap, unsigned int remap_len); @@ -135,7 +139,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(struct Main *bmain, struct Scene *sce, struct Object *ob, +struct Mesh *BKE_mesh_new_from_object(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, struct Object *ob, int apply_modifiers, int settings, int calc_tessface, int calc_undeformed); /* vertex level transformations & checks (no derived mesh) */ @@ -396,8 +400,6 @@ void BKE_mesh_calc_edges(struct Mesh *mesh, bool update, const bool select); /* **** Depsgraph evaluation **** */ -struct EvaluationContext; - void BKE_mesh_eval_geometry(struct EvaluationContext *eval_ctx, struct Mesh *mesh); diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 95f28f8fa6f..ca74993156d 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -36,6 +36,7 @@ struct ID; struct DerivedMesh; struct DagForest; struct DagNode; +struct EvaluationContext; struct Object; struct Scene; struct SceneLayer; @@ -158,25 +159,27 @@ typedef struct ModifierTypeInfo { * the object it can obtain it from the derivedData argument if non-NULL, * and otherwise the ob argument. */ - void (*deformVerts)(struct ModifierData *md, struct Object *ob, - struct DerivedMesh *derivedData, + void (*deformVerts)(struct ModifierData *md, struct EvaluationContext *eval_ctx, + struct Object *ob, struct DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag flag); /* Like deformMatricesEM but called from object mode (for supporting modifiers in sculpt mode) */ - void (*deformMatrices)(struct ModifierData *md, struct Object *ob, - struct DerivedMesh *derivedData, + void (*deformMatrices)(struct ModifierData *md, struct EvaluationContext *eval_ctx, + struct Object *ob, struct DerivedMesh *derivedData, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts); /* Like deformVerts but called during editmode (for supporting modifiers) */ - void (*deformVertsEM)(struct ModifierData *md, struct Object *ob, - struct BMEditMesh *editData, struct DerivedMesh *derivedData, + void (*deformVertsEM)(struct ModifierData *md, struct EvaluationContext *eval_ctx, + struct Object *ob, struct BMEditMesh *editData, + struct DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts); /* Set deform matrix per vertex for crazyspace correction */ - void (*deformMatricesEM)(struct ModifierData *md, struct Object *ob, - struct BMEditMesh *editData, struct DerivedMesh *derivedData, + void (*deformMatricesEM)(struct ModifierData *md, struct EvaluationContext *eval_ctx, + struct Object *ob, struct BMEditMesh *editData, + struct DerivedMesh *derivedData, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts); /********************* Non-deform modifier functions *********************/ @@ -200,8 +203,8 @@ typedef struct ModifierTypeInfo { * The modifier may reuse the derivedData argument (i.e. return it in * modified form), but must not release it. */ - struct DerivedMesh *(*applyModifier)(struct ModifierData *md, struct Object *ob, - struct DerivedMesh *derivedData, + struct DerivedMesh *(*applyModifier)(struct ModifierData *md, struct EvaluationContext *eval_ctx, + struct Object *ob, struct DerivedMesh *derivedData, ModifierApplyFlag flag); /* Like applyModifier but called during editmode (for supporting @@ -211,10 +214,9 @@ typedef struct ModifierTypeInfo { * are expected from editmode objects. The same qualifications regarding * derivedData apply as for applyModifier. */ - struct DerivedMesh *(*applyModifierEM)(struct ModifierData *md, struct Object *ob, - struct BMEditMesh *editData, - struct DerivedMesh *derivedData, - ModifierApplyFlag flag); + struct DerivedMesh *(*applyModifierEM)(struct ModifierData *md, struct EvaluationContext *eval_ctx, + struct Object *ob, struct BMEditMesh *editData, + struct DerivedMesh *derivedData, ModifierApplyFlag flag); /********************* Optional functions *********************/ @@ -417,24 +419,24 @@ const char *modifier_path_relbase(struct Object *ob); /* wrappers for modifier callbacks */ struct DerivedMesh *modwrap_applyModifier( - ModifierData *md, struct Object *ob, - struct DerivedMesh *dm, + ModifierData *md, struct EvaluationContext *eval_ctx, + struct Object *ob, struct DerivedMesh *dm, ModifierApplyFlag flag); struct DerivedMesh *modwrap_applyModifierEM( - ModifierData *md, struct Object *ob, - struct BMEditMesh *em, + ModifierData *md, struct EvaluationContext *eval_ctx, + struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, ModifierApplyFlag flag); void modwrap_deformVerts( - ModifierData *md, struct Object *ob, - struct DerivedMesh *dm, + ModifierData *md, struct EvaluationContext *eval_ctx, + struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts, ModifierApplyFlag flag); void modwrap_deformVertsEM( - ModifierData *md, struct Object *ob, + ModifierData *md, struct EvaluationContext *eval_ctx, struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts); diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 178751d1640..5ddc67b7a8c 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -34,6 +34,7 @@ enum MultiresModifiedFlags; struct DerivedMesh; +struct EvaluationContext; struct MDisps; struct Mesh; struct ModifierData; @@ -80,18 +81,18 @@ struct DerivedMesh *multires_make_derived_from_derived(struct DerivedMesh *dm, struct MultiresModifierData *find_multires_modifier_before(struct Scene *scene, struct ModifierData *lastmd); struct MultiresModifierData *get_multires_modifier(struct Scene *scene, struct Object *ob, bool use_first); -struct DerivedMesh *get_multires_dm(struct Scene *scene, struct MultiresModifierData *mmd, +struct DerivedMesh *get_multires_dm(struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd, struct Object *ob); void multiresModifier_del_levels(struct MultiresModifierData *, struct Object *, int direction); void multiresModifier_base_apply(struct MultiresModifierData *mmd, struct Object *ob); void multiresModifier_subdivide(struct MultiresModifierData *mmd, struct Object *ob, int updateblock, int simple); void multiresModifier_sync_levels_ex( struct Object *ob_dst, struct MultiresModifierData *mmd_src, struct MultiresModifierData *mmd_dst); -int multiresModifier_reshape(struct Scene *scene, struct MultiresModifierData *mmd, +int multiresModifier_reshape(struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd, struct Object *dst, struct Object *src); -int multiresModifier_reshapeFromDM(struct Scene *scene, struct MultiresModifierData *mmd, +int multiresModifier_reshapeFromDM(struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd, struct Object *ob, struct DerivedMesh *srcdm); -int multiresModifier_reshapeFromDeformMod(struct Scene *scene, struct MultiresModifierData *mmd, +int multiresModifier_reshapeFromDeformMod(struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd, struct Object *ob, struct ModifierData *md); void multires_stitch_grids(struct Object *); @@ -109,8 +110,8 @@ void multires_free(struct Multires *mr); void multires_load_old(struct Object *ob, struct Mesh *me); void multires_load_old_250(struct Mesh *); -void multiresModifier_scale_disp(struct Scene *scene, struct Object *ob); -void multiresModifier_prepare_join(struct Scene *scene, struct Object *ob, struct Object *to_ob); +void multiresModifier_scale_disp(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); +void multiresModifier_prepare_join(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct Object *to_ob); int multires_mdisp_corners(struct MDisps *s); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index c3de20d7089..d763b33b88f 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -51,7 +51,7 @@ struct HookModifierData; struct ModifierData; void BKE_object_workob_clear(struct Object *workob); -void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struct Object *workob); +void BKE_object_workob_calc_parent(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct Object *workob); void BKE_object_transform_copy(struct Object *ob_tar, const struct Object *ob_src); struct SoftBody *copy_softbody(const struct SoftBody *sb, bool copy_caches); @@ -126,11 +126,12 @@ void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4]); bool BKE_object_pose_context_check(struct Object *ob); struct Object *BKE_object_pose_armature_get(struct Object *ob); -void BKE_object_get_parent_matrix(struct Scene *scene, struct Object *ob, struct Object *par, float parentmat[4][4]); -void BKE_object_where_is_calc(struct Scene *scene, struct Object *ob); -void BKE_object_where_is_calc_ex(struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob, float r_originmat[3][3]); -void BKE_object_where_is_calc_time(struct Scene *scene, struct Object *ob, float ctime); -void BKE_object_where_is_calc_time_ex(struct Scene *scene, struct Object *ob, float ctime, +void BKE_object_get_parent_matrix(struct Scene *scene, struct Object *ob, + struct Object *par, float parentmat[4][4]); +void BKE_object_where_is_calc(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); +void BKE_object_where_is_calc_ex(struct EvaluationContext *eval_ctx, struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob, float r_originmat[3][3]); +void BKE_object_where_is_calc_time(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime); +void BKE_object_where_is_calc_time_ex(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime, struct RigidBodyWorld *rbw, float r_originmat[3][3]); void BKE_object_where_is_calc_mat4(struct Scene *scene, struct Object *ob, float obmat[4][4]); @@ -261,9 +262,8 @@ struct KDTree *BKE_object_as_kdtree(struct Object *ob, int *r_tot); bool BKE_object_modifier_use_time(struct Object *ob, struct ModifierData *md); -bool BKE_object_modifier_update_subframe(struct Scene *scene, struct Object *ob, bool update_mesh, - int parent_recursion, float frame, - int type); +bool BKE_object_modifier_update_subframe(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, + bool update_mesh, int parent_recursion, float frame, int type); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 787a67170c2..e9287465528 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -58,6 +58,7 @@ struct StrokeCache; struct Tex; struct ImagePool; struct UnifiedPaintSettings; +struct EvaluationContext; enum OverlayFlags; @@ -208,7 +209,7 @@ void BKE_sculptsession_free(struct Object *ob); void BKE_sculptsession_free_deformMats(struct SculptSession *ss); void BKE_sculptsession_bm_to_me(struct Object *ob, bool reorder); void BKE_sculptsession_bm_to_me_for_render(struct Object *object); -void BKE_sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob, +void BKE_sculpt_update_mesh_elements(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Sculpt *sd, struct Object *ob, bool need_pmap, bool need_mask); struct MultiresModifierData *BKE_sculpt_multires_active(struct Scene *scene, struct Object *ob); int BKE_sculpt_mask_layers_ensure(struct Object *ob, diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 4951ecc7f9e..52922271689 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -62,6 +62,7 @@ struct RNG; struct BVHTreeRay; struct BVHTreeRayHit; struct EdgeHash; +struct EvaluationContext; #define PARTICLE_COLLISION_MAX_COLLISIONS 10 @@ -77,6 +78,7 @@ struct EdgeHash; /* common stuff that many particle functions need */ typedef struct ParticleSimulationData { + struct EvaluationContext *eval_ctx; struct Scene *scene; struct Object *ob; struct ParticleSystem *psys; @@ -332,9 +334,9 @@ void psys_reset(struct ParticleSystem *psys, int mode); void psys_find_parents(struct ParticleSimulationData *sim, const bool use_render_params); void psys_cache_paths(struct ParticleSimulationData *sim, float cfra, const bool use_render_params); -void psys_cache_edit_paths(struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra, const bool use_render_params); +void psys_cache_edit_paths(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra, const bool use_render_params); void psys_cache_child_paths(struct ParticleSimulationData *sim, float cfra, const bool editupdate, const bool use_render_params); -int do_guides(struct ParticleSettings *part, struct ListBase *effectors, ParticleKey *state, int pa_num, float time); +int do_guides(struct EvaluationContext *eval_ctx, struct ParticleSettings *part, struct ListBase *effectors, ParticleKey *state, int pa_num, float time); void precalc_guides(struct ParticleSimulationData *sim, struct ListBase *effectors); float psys_get_timestep(struct ParticleSimulationData *sim); float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime); @@ -366,7 +368,7 @@ void psys_tasks_create(struct ParticleThreadContext *ctx, int startpart, int end void psys_tasks_free(struct ParticleTask *tasks, int numtasks); void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]); -void psys_apply_hair_lattice(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys); +void psys_apply_hair_lattice(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys); /* particle_system.c */ struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt); @@ -381,7 +383,7 @@ void psys_check_boid_data(struct ParticleSystem *psys); void psys_get_birth_coords(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, float dtime, float cfra); -void particle_system_update(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, const bool use_render_params); +void particle_system_update(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, const bool use_render_params); /* Callback format for performing operations on ID-pointers for particle systems */ typedef void (*ParticleSystemIDFunc)(struct ParticleSystem *psys, struct ID **idpoin, void *userdata, int cb_flag); @@ -474,10 +476,14 @@ typedef struct ParticleRenderData { struct EvaluationContext; -void BKE_particle_system_eval(struct EvaluationContext *eval_ctx, - struct Scene *scene, - struct Object *ob, - struct ParticleSystem *psys); +void BKE_particle_system_settings_eval(struct EvaluationContext *eval_ctx, + struct ParticleSystem *psys); +void BKE_particle_system_settings_recalc_clear(struct EvaluationContext *UNUSED(eval_ctx), + struct ParticleSettings *particle_settings); + +void BKE_particle_system_eval_init(struct EvaluationContext *eval_ctx, + struct Scene *scene, + struct Object *ob); #endif diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h index c72f067a111..41e2a117eeb 100644 --- a/source/blender/blenkernel/BKE_rigidbody.h +++ b/source/blender/blenkernel/BKE_rigidbody.h @@ -37,6 +37,7 @@ struct RigidBodyWorld; struct RigidBodyOb; +struct EvaluationContext; struct Scene; struct Object; @@ -99,14 +100,12 @@ void BKE_rigidbody_aftertrans_update(struct Object *ob, float loc[3], float rot[ void BKE_rigidbody_sync_transforms(struct RigidBodyWorld *rbw, struct Object *ob, float ctime); bool BKE_rigidbody_check_sim_running(struct RigidBodyWorld *rbw, float ctime); void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw); -void BKE_rigidbody_rebuild_world(struct Scene *scene, float ctime); -void BKE_rigidbody_do_simulation(struct Scene *scene, float ctime); +void BKE_rigidbody_rebuild_world(struct EvaluationContext *eval_ctx, struct Scene *scene, float ctime); +void BKE_rigidbody_do_simulation(struct EvaluationContext *eval_ctx, struct Scene *scene, float ctime); /* -------------------- */ /* Depsgraph evaluation */ -struct EvaluationContext; - void BKE_rigidbody_rebuild_sim(struct EvaluationContext *eval_ctx, struct Scene *scene); diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 6ff344fea38..3cb78a427ab 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -294,6 +294,7 @@ void BKE_area_region_free(struct SpaceType *st, struct ARegion *ar); void BKE_screen_area_free(struct ScrArea *sa); /* Manipulator-maps of a region need to be freed with the region. Uses callback to avoid low-level call. */ void BKE_region_callback_free_manipulatormap_set(void (*callback)(struct wmManipulatorMap *)); +void BKE_region_callback_refresh_tag_manipulatormap_set(void (*callback)(struct wmManipulatorMap *)); struct ARegion *BKE_area_find_region_type(struct ScrArea *sa, int type); struct ARegion *BKE_area_find_region_active_win(struct ScrArea *sa); @@ -309,6 +310,8 @@ unsigned int BKE_screen_view3d_layer_active( unsigned int BKE_screen_view3d_layer_all(const struct bScreen *sc) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +void BKE_screen_manipulator_tag_refresh(struct bScreen *sc); + void BKE_screen_view3d_sync(struct View3D *v3d, struct Scene *scene); void BKE_screen_view3d_scene_sync(struct bScreen *sc, struct Scene *scene); void BKE_screen_transform_orientation_remove( diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 7c09cafaf64..5a2c49f5527 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -421,7 +421,7 @@ struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C, ListBase *seq /* view3d draw callback, run when not in background view */ typedef struct ImBuf *(*SequencerDrawView)( - struct Scene *, struct SceneLayer *sl, struct Object *, int, int, + struct EvaluationContext *eval_ctx, struct Scene *, struct SceneLayer *sl, struct Object *, int, int, unsigned int, int, bool, bool, bool, int, int, bool, const char *, struct GPUFX *, struct GPUOffScreen *, char[256]); diff --git a/source/blender/blenkernel/BKE_smoke.h b/source/blender/blenkernel/BKE_smoke.h index 33d7acdd864..40b349c9cbc 100644 --- a/source/blender/blenkernel/BKE_smoke.h +++ b/source/blender/blenkernel/BKE_smoke.h @@ -35,7 +35,9 @@ typedef float (*bresenham_callback)(float *result, float *input, int res[3], int *pixel, float *tRay, float correct); -struct DerivedMesh *smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct SceneLayer *sl, struct Object *ob, struct DerivedMesh *dm); +struct DerivedMesh *smokeModifier_do(struct SmokeModifierData *smd, struct EvaluationContext *eval_ctx, + struct Scene *scene, + struct Object *ob, struct DerivedMesh *dm); void smoke_reallocate_fluid(struct SmokeDomainSettings *sds, float dx, int res[3], int free_old); void smoke_reallocate_highres_fluid(struct SmokeDomainSettings *sds, float dx, int res[3], int free_old); diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h index 75c5faf4088..89aaf4b39ec 100644 --- a/source/blender/blenkernel/BKE_softbody.h +++ b/source/blender/blenkernel/BKE_softbody.h @@ -34,6 +34,7 @@ struct Object; struct Scene; struct SoftBody; +struct EvaluationContext; typedef struct BodyPoint { float origS[3], origE[3], origT[3], pos[3], vec[3], force[3]; @@ -59,7 +60,7 @@ extern void sbFree(struct SoftBody *sb); extern void sbFreeSimulation(struct SoftBody *sb); /* do one simul step, reading and writing vertex locs from given array */ -extern void sbObjectStep(struct Scene *scene, struct SceneLayer *sl, struct Object *ob, +extern void sbObjectStep(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float framnr, float (*vertexCos)[3], int numVerts); /* makes totally fresh start situation, resets time */ diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index b48be382073..d149654fc82 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -47,6 +47,7 @@ struct MovieDistortion; struct Camera; struct Object; struct Scene; +struct EvaluationContext; struct rcti; /* **** Common functions **** */ diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h index 18ae61f7653..5175edcd3d6 100644 --- a/source/blender/blenkernel/BKE_world.h +++ b/source/blender/blenkernel/BKE_world.h @@ -43,5 +43,11 @@ struct World *BKE_world_copy(struct Main *bmain, const struct World *wrld); struct World *localize_world(struct World *wrld); void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local); +/* Evaluation. */ + +struct EvaluationContext; + +void BKE_world_eval(struct EvaluationContext *eval_ctx, struct World *world); + #endif diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 675b4fa48da..40177de1128 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -437,6 +437,10 @@ if(WITH_PYTHON) ) add_definitions(-DWITH_PYTHON) + if(WITH_PYTHON_SAFETY) + add_definitions(-DWITH_PYTHON_SAFETY) + endif() + if(WITH_PYTHON_SECURITY) add_definitions(-DWITH_PYTHON_SECURITY) endif() diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index a26fdd85d52..7b3eebb45dc 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1126,7 +1126,7 @@ DerivedMesh *mesh_create_derived(Mesh *me, float (*vertCos)[3]) } DerivedMesh *mesh_create_derived_for_modifier( - Scene *scene, Object *ob, + struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, ModifierData *md, int build_shapekey_layers) { Mesh *me = ob->data; @@ -1152,7 +1152,7 @@ DerivedMesh *mesh_create_derived_for_modifier( int numVerts; float (*deformedVerts)[3] = BKE_mesh_vertexCos_get(me, &numVerts); - modwrap_deformVerts(md, ob, NULL, deformedVerts, numVerts, 0); + modwrap_deformVerts(md, eval_ctx, ob, NULL, deformedVerts, numVerts, 0); dm = mesh_create_derived(me, deformedVerts); if (build_shapekey_layers) @@ -1166,7 +1166,7 @@ DerivedMesh *mesh_create_derived_for_modifier( if (build_shapekey_layers) add_shapekey_layers(tdm, me, ob); - dm = modwrap_applyModifier(md, ob, tdm, 0); + dm = modwrap_applyModifier(md, eval_ctx, ob, tdm, 0); ASSERT_IS_VALID_DM(dm); if (tdm != dm) tdm->release(tdm); @@ -1732,7 +1732,7 @@ static void dm_ensure_display_normals(DerivedMesh *dm) * - apply deform modifiers and input vertexco */ static void mesh_calc_modifiers( - Scene *scene, Object *ob, float (*inputVertexCos)[3], + struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (*inputVertexCos)[3], const bool useRenderParams, int useDeform, const bool need_mapping, CustomDataMask dataMask, const int index, const bool useCache, const bool build_shapekey_layers, @@ -1843,7 +1843,7 @@ static void mesh_calc_modifiers( if (!deformedVerts) deformedVerts = BKE_mesh_vertexCos_get(me, &numVerts); - modwrap_deformVerts(md, ob, NULL, deformedVerts, numVerts, deform_app_flags); + modwrap_deformVerts(md, eval_ctx, ob, NULL, deformedVerts, numVerts, deform_app_flags); } else { break; @@ -1984,7 +1984,7 @@ static void mesh_calc_modifiers( } } - modwrap_deformVerts(md, ob, dm, deformedVerts, numVerts, deform_app_flags); + modwrap_deformVerts(md, eval_ctx, ob, dm, deformedVerts, numVerts, deform_app_flags); } else { DerivedMesh *ndm; @@ -2059,7 +2059,7 @@ static void mesh_calc_modifiers( } } - ndm = modwrap_applyModifier(md, ob, dm, app_flags); + ndm = modwrap_applyModifier(md, eval_ctx, ob, dm, app_flags); ASSERT_IS_VALID_DM(ndm); if (ndm) { @@ -2086,7 +2086,7 @@ static void mesh_calc_modifiers( (mti->requiredDataMask ? mti->requiredDataMask(ob, md) : 0)); - ndm = modwrap_applyModifier(md, ob, orcodm, (app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO); + ndm = modwrap_applyModifier(md, eval_ctx, ob, orcodm, (app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO); ASSERT_IS_VALID_DM(ndm); if (ndm) { @@ -2104,7 +2104,7 @@ static void mesh_calc_modifiers( nextmask &= ~CD_MASK_CLOTH_ORCO; DM_set_only_copy(clothorcodm, nextmask | CD_MASK_ORIGINDEX); - ndm = modwrap_applyModifier(md, ob, clothorcodm, (app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO); + ndm = modwrap_applyModifier(md, eval_ctx, ob, clothorcodm, (app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO); ASSERT_IS_VALID_DM(ndm); if (ndm) { @@ -2288,8 +2288,8 @@ bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh * } static void editbmesh_calc_modifiers( - Scene *scene, Object *ob, BMEditMesh *em, - CustomDataMask dataMask, + struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, + BMEditMesh *em, CustomDataMask dataMask, /* return args */ DerivedMesh **r_cage, DerivedMesh **r_final) { @@ -2376,9 +2376,9 @@ static void editbmesh_calc_modifiers( } if (mti->deformVertsEM) - modwrap_deformVertsEM(md, ob, em, dm, deformedVerts, numVerts); + modwrap_deformVertsEM(md, eval_ctx, ob, em, dm, deformedVerts, numVerts); else - modwrap_deformVerts(md, ob, dm, deformedVerts, numVerts, 0); + modwrap_deformVerts(md, eval_ctx, ob, dm, deformedVerts, numVerts, 0); } else { DerivedMesh *ndm; @@ -2423,10 +2423,10 @@ static void editbmesh_calc_modifiers( DM_set_only_copy(orcodm, mask | CD_MASK_ORIGINDEX); if (mti->applyModifierEM) { - ndm = modwrap_applyModifierEM(md, ob, em, orcodm, MOD_APPLY_ORCO); + ndm = modwrap_applyModifierEM(md, eval_ctx, ob, em, orcodm, MOD_APPLY_ORCO); } else { - ndm = modwrap_applyModifier(md, ob, orcodm, MOD_APPLY_ORCO); + ndm = modwrap_applyModifier(md, eval_ctx, ob, orcodm, MOD_APPLY_ORCO); } ASSERT_IS_VALID_DM(ndm); @@ -2451,9 +2451,9 @@ static void editbmesh_calc_modifiers( } if (mti->applyModifierEM) - ndm = modwrap_applyModifierEM(md, ob, em, dm, MOD_APPLY_USECACHE | MOD_APPLY_ALLOW_GPU); + ndm = modwrap_applyModifierEM(md, eval_ctx, ob, em, dm, MOD_APPLY_USECACHE | MOD_APPLY_ALLOW_GPU); else - ndm = modwrap_applyModifier(md, ob, dm, MOD_APPLY_USECACHE | MOD_APPLY_ALLOW_GPU); + ndm = modwrap_applyModifier(md, eval_ctx, ob, dm, MOD_APPLY_USECACHE | MOD_APPLY_ALLOW_GPU); ASSERT_IS_VALID_DM(ndm); if (ndm) { @@ -2618,7 +2618,7 @@ static bool calc_modifiers_skip_orco(Scene *scene, #endif static void mesh_build_data( - Scene *scene, Object *ob, CustomDataMask dataMask, + struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask, const bool build_shapekey_layers, const bool need_mapping) { BLI_assert(ob->type == OB_MESH); @@ -2633,7 +2633,7 @@ static void mesh_build_data( #endif mesh_calc_modifiers( - scene, ob, NULL, false, 1, need_mapping, dataMask, -1, true, build_shapekey_layers, + eval_ctx, scene, ob, NULL, false, 1, need_mapping, dataMask, -1, true, build_shapekey_layers, true, &ob->derivedDeform, &ob->derivedFinal); @@ -2648,13 +2648,13 @@ static void mesh_build_data( /* create PBVH immediately (would be created on the fly too, * but this avoids waiting on first stroke) */ - BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, false, false); + BKE_sculpt_update_mesh_elements(eval_ctx, scene, scene->toolsettings->sculpt, ob, false, false); } BLI_assert(!(ob->derivedFinal->dirty & DM_DIRTY_NORMALS)); } -static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask) +static void editbmesh_build_data(struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask) { BKE_object_free_derived_caches(obedit); BKE_object_sculpt_modifiers_changed(obedit); @@ -2668,7 +2668,7 @@ static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, C #endif editbmesh_calc_modifiers( - scene, obedit, em, dataMask, + eval_ctx, scene, obedit, em, dataMask, &em->derivedCage, &em->derivedFinal); DM_set_object_boundbox(obedit, em->derivedFinal); @@ -2721,23 +2721,23 @@ static CustomDataMask object_get_datamask(const Scene *scene, Object *ob, bool * } void makeDerivedMesh( - Scene *scene, Object *ob, BMEditMesh *em, + struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BMEditMesh *em, CustomDataMask dataMask, const bool build_shapekey_layers) { bool need_mapping; dataMask |= object_get_datamask(scene, ob, &need_mapping); if (em) { - editbmesh_build_data(scene, ob, em, dataMask); + editbmesh_build_data(eval_ctx, scene, ob, em, dataMask); } else { - mesh_build_data(scene, ob, dataMask, build_shapekey_layers, need_mapping); + mesh_build_data(eval_ctx, scene, ob, dataMask, build_shapekey_layers, need_mapping); } } /***/ -DerivedMesh *mesh_get_derived_final(Scene *scene, Object *ob, CustomDataMask dataMask) +DerivedMesh *mesh_get_derived_final(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask) { /* if there's no derived mesh or the last data mask used doesn't include * the data we need, rebuild the derived mesh @@ -2749,14 +2749,14 @@ DerivedMesh *mesh_get_derived_final(Scene *scene, Object *ob, CustomDataMask dat ((dataMask & ob->lastDataMask) != dataMask) || (need_mapping != ob->lastNeedMapping)) { - mesh_build_data(scene, ob, dataMask, false, need_mapping); + mesh_build_data(eval_ctx, scene, ob, dataMask, false, need_mapping); } if (ob->derivedFinal) { BLI_assert(!(ob->derivedFinal->dirty & DM_DIRTY_NORMALS)); } return ob->derivedFinal; } -DerivedMesh *mesh_get_derived_deform(Scene *scene, Object *ob, CustomDataMask dataMask) +DerivedMesh *mesh_get_derived_deform(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask) { /* if there's no derived mesh or the last data mask used doesn't include * the data we need, rebuild the derived mesh @@ -2769,37 +2769,37 @@ DerivedMesh *mesh_get_derived_deform(Scene *scene, Object *ob, CustomDataMask da ((dataMask & ob->lastDataMask) != dataMask) || (need_mapping != ob->lastNeedMapping)) { - mesh_build_data(scene, ob, dataMask, false, need_mapping); + mesh_build_data(eval_ctx, scene, ob, dataMask, false, need_mapping); } return ob->derivedDeform; } -DerivedMesh *mesh_create_derived_render(Scene *scene, Object *ob, CustomDataMask dataMask) +DerivedMesh *mesh_create_derived_render(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask) { DerivedMesh *final; mesh_calc_modifiers( - scene, ob, NULL, true, 1, false, dataMask, -1, false, false, false, + eval_ctx, scene, ob, NULL, true, 1, false, dataMask, -1, false, false, false, NULL, &final); return final; } -DerivedMesh *mesh_create_derived_index_render(Scene *scene, Object *ob, CustomDataMask dataMask, int index) +DerivedMesh *mesh_create_derived_index_render(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask, int index) { DerivedMesh *final; mesh_calc_modifiers( - scene, ob, NULL, true, 1, false, dataMask, index, false, false, false, + eval_ctx, scene, ob, NULL, true, 1, false, dataMask, index, false, false, false, NULL, &final); return final; } DerivedMesh *mesh_create_derived_view( - Scene *scene, Object *ob, - CustomDataMask dataMask) + struct EvaluationContext *eval_ctx, Scene *scene, + Object *ob, CustomDataMask dataMask) { DerivedMesh *final; @@ -2810,7 +2810,7 @@ DerivedMesh *mesh_create_derived_view( ob->transflag |= OB_NO_PSYS_UPDATE; mesh_calc_modifiers( - scene, ob, NULL, false, 1, false, dataMask, -1, false, false, false, + eval_ctx, scene, ob, NULL, false, 1, false, dataMask, -1, false, false, false, NULL, &final); ob->transflag &= ~OB_NO_PSYS_UPDATE; @@ -2819,53 +2819,53 @@ DerivedMesh *mesh_create_derived_view( } DerivedMesh *mesh_create_derived_no_deform( - Scene *scene, Object *ob, float (*vertCos)[3], - CustomDataMask dataMask) + struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, + float (*vertCos)[3], CustomDataMask dataMask) { DerivedMesh *final; mesh_calc_modifiers( - scene, ob, vertCos, false, 0, false, dataMask, -1, false, false, false, + eval_ctx, scene, ob, vertCos, false, 0, false, dataMask, -1, false, false, false, NULL, &final); return final; } DerivedMesh *mesh_create_derived_no_virtual( - Scene *scene, Object *ob, float (*vertCos)[3], - CustomDataMask dataMask) + struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, + float (*vertCos)[3], CustomDataMask dataMask) { DerivedMesh *final; mesh_calc_modifiers( - scene, ob, vertCos, false, -1, false, dataMask, -1, false, false, false, + eval_ctx, scene, ob, vertCos, false, -1, false, dataMask, -1, false, false, false, NULL, &final); return final; } DerivedMesh *mesh_create_derived_physics( - Scene *scene, Object *ob, float (*vertCos)[3], - CustomDataMask dataMask) + struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, + float (*vertCos)[3], CustomDataMask dataMask) { DerivedMesh *final; mesh_calc_modifiers( - scene, ob, vertCos, false, -1, true, dataMask, -1, false, false, false, + eval_ctx, scene, ob, vertCos, false, -1, true, dataMask, -1, false, false, false, NULL, &final); return final; } DerivedMesh *mesh_create_derived_no_deform_render( - Scene *scene, Object *ob, - float (*vertCos)[3], + struct EvaluationContext *eval_ctx, Scene *scene, + Object *ob, float (*vertCos)[3], CustomDataMask dataMask) { DerivedMesh *final; mesh_calc_modifiers( - scene, ob, vertCos, true, 0, false, dataMask, -1, false, false, false, + eval_ctx, scene, ob, vertCos, true, 0, false, dataMask, -1, false, false, false, NULL, &final); return final; @@ -2874,7 +2874,7 @@ DerivedMesh *mesh_create_derived_no_deform_render( /***/ DerivedMesh *editbmesh_get_derived_cage_and_final( - Scene *scene, Object *obedit, BMEditMesh *em, + struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask, /* return args */ DerivedMesh **r_final) @@ -2887,7 +2887,7 @@ DerivedMesh *editbmesh_get_derived_cage_and_final( if (!em->derivedCage || (em->lastDataMask & dataMask) != dataMask) { - editbmesh_build_data(scene, obedit, em, dataMask); + editbmesh_build_data(eval_ctx, scene, obedit, em, dataMask); } *r_final = em->derivedFinal; @@ -2895,7 +2895,7 @@ DerivedMesh *editbmesh_get_derived_cage_and_final( return em->derivedCage; } -DerivedMesh *editbmesh_get_derived_cage(Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask) +DerivedMesh *editbmesh_get_derived_cage(struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask) { /* if there's no derived mesh or the last data mask used doesn't include * the data we need, rebuild the derived mesh @@ -2905,7 +2905,7 @@ DerivedMesh *editbmesh_get_derived_cage(Scene *scene, Object *obedit, BMEditMesh if (!em->derivedCage || (em->lastDataMask & dataMask) != dataMask) { - editbmesh_build_data(scene, obedit, em, dataMask); + editbmesh_build_data(eval_ctx, scene, obedit, em, dataMask); } return em->derivedCage; diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 59484724aee..34ab8a064d4 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -43,6 +43,7 @@ #include "DNA_key_types.h" #include "DNA_scene_types.h" +#include "BKE_context.h" #include "BKE_curve.h" #include "BKE_global.h" #include "BKE_key.h" @@ -282,10 +283,11 @@ void animviz_get_object_motionpaths(Object *ob, ListBase *targets) */ /* tweak the object ordering to trick depsgraph into making MotionPath calculations run faster */ -static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets) +static void motionpaths_calc_optimise_depsgraph(bContext *C, Scene *scene, ListBase *targets) { BaseLegacy *base, *baseNext; MPathTarget *mpt; + Main *bmain = CTX_data_main(C); /* make sure our temp-tag isn't already in use */ for (base = scene->base.first; base; base = base->next) @@ -309,7 +311,7 @@ static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets) } /* "brew me a list that's sorted a bit faster now depsy" */ - DEG_scene_relations_rebuild(G.main, scene); + DEG_scene_relations_rebuild(bmain, scene); } /* update scene for current frame */ @@ -373,7 +375,7 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets) * - recalc: whether we need to */ /* TODO: include reports pointer? */ -void animviz_calc_motionpaths(Scene *scene, ListBase *targets) +void animviz_calc_motionpaths(bContext *C, Scene *scene, ListBase *targets) { MPathTarget *mpt; int sfra, efra; @@ -399,7 +401,7 @@ void animviz_calc_motionpaths(Scene *scene, ListBase *targets) /* optimize the depsgraph for faster updates */ /* TODO: whether this is used should depend on some setting for the level of optimizations used */ - motionpaths_calc_optimise_depsgraph(scene, targets); + motionpaths_calc_optimise_depsgraph(C, scene, targets); /* calculate path over requested range */ for (CFRA = sfra; CFRA <= efra; CFRA++) { diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 38b98f1eee6..81796683761 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1445,13 +1445,13 @@ void BKE_armature_loc_pose_to_bone(bPoseChannel *pchan, const float inloc[3], fl copy_v3_v3(outloc, nLocMat[3]); } -void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]) +void BKE_armature_mat_pose_to_bone_ex(struct EvaluationContext *eval_ctx, Object *ob, bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]) { bPoseChannel work_pchan = *pchan; /* recalculate pose matrix with only parent transformations, * bone loc/sca/rot is ignored, scene and frame are not used. */ - BKE_pose_where_is_bone(NULL, ob, &work_pchan, 0.0f, false); + BKE_pose_where_is_bone(eval_ctx, NULL, ob, &work_pchan, 0.0f, false); /* find the matrix, need to remove the bone transforms first so this is * calculated as a matrix to set rather then a difference ontop of whats @@ -2178,7 +2178,7 @@ void BKE_pose_where_is_bone_tail(bPoseChannel *pchan) /* pchan is validated, as having bone and parent pointer * 'do_extra': when zero skips loc/size/rot, constraints and strip modifiers. */ -void BKE_pose_where_is_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float ctime, bool do_extra) +void BKE_pose_where_is_bone(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan, float ctime, bool do_extra) { /* This gives a chan_mat with actions (ipos) results. */ if (do_extra) @@ -2217,7 +2217,7 @@ void BKE_pose_where_is_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float cob = BKE_constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE); /* Solve PoseChannel's Constraints */ - BKE_constraints_solve(&pchan->constraints, cob, ctime); /* ctime doesnt alter objects */ + BKE_constraints_solve(eval_ctx, &pchan->constraints, cob, ctime); /* ctime doesnt alter objects */ /* cleanup after Constraint Solving * - applies matrix back to pchan, and frees temporary struct used @@ -2239,7 +2239,7 @@ void BKE_pose_where_is_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float /* This only reads anim data from channels, and writes to channels */ /* This is the only function adding poses */ -void BKE_pose_where_is(Scene *scene, Object *ob) +void BKE_pose_where_is(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob) { bArmature *arm; Bone *bone; @@ -2278,7 +2278,7 @@ void BKE_pose_where_is(Scene *scene, Object *ob) } /* 2a. construct the IK tree (standard IK) */ - BIK_initialize_tree(scene, ob, ctime); + BIK_initialize_tree(eval_ctx, scene, ob, ctime); /* 2b. construct the Spline IK trees * - this is not integrated as an IK plugin, since it should be able @@ -2290,15 +2290,15 @@ void BKE_pose_where_is(Scene *scene, Object *ob) for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { /* 4a. if we find an IK root, we handle it separated */ if (pchan->flag & POSE_IKTREE) { - BIK_execute_tree(scene, ob, pchan, ctime); + BIK_execute_tree(eval_ctx, scene, ob, pchan, ctime); } /* 4b. if we find a Spline IK root, we handle it separated too */ else if (pchan->flag & POSE_IKSPLINE) { - BKE_splineik_execute_tree(scene, ob, pchan, ctime); + BKE_splineik_execute_tree(eval_ctx, scene, ob, pchan, ctime); } /* 5. otherwise just call the normal solver */ else if (!(pchan->flag & POSE_DONE)) { - BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1); + BKE_pose_where_is_bone(eval_ctx, scene, ob, pchan, ctime, 1); } } /* 6. release the IK tree */ diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index 73e9f5d0774..5d579b97619 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -113,9 +113,11 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos * currently for paths to work it needs to go through the bevlist/displist system (ton) */ + /* TODO: Make sure this doesn't crash. */ +#if 0 /* only happens on reload file, but violates depsgraph still... fix! */ if (ELEM(NULL, ikData->tar->curve_cache, ikData->tar->curve_cache->path, ikData->tar->curve_cache->path->data)) { - BKE_displist_make_curveTypes(scene, ikData->tar, 0); + BKE_displist_make_curveTypes(eval_ctx, scene, ikData->tar, 0); /* path building may fail in EditMode after removing verts [#33268]*/ if (ELEM(NULL, ikData->tar->curve_cache->path, ikData->tar->curve_cache->path->data)) { @@ -123,6 +125,9 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos return; } } +#else + (void) scene; +#endif } /* find the root bone and the chain of bones from the root to the tip @@ -261,7 +266,7 @@ static void splineik_init_tree(Scene *scene, Object *ob, float UNUSED(ctime)) /* ----------- */ /* Evaluate spline IK for a given bone */ -static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *ob, bPoseChannel *pchan, +static void splineik_evaluate_bone(struct EvaluationContext *eval_ctx, tSplineIK_Tree *tree, Scene *scene, Object *ob, bPoseChannel *pchan, int index, float ctime) { bSplineIKConstraint *ikData = tree->ikData; @@ -269,7 +274,7 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o float splineVec[3], scaleFac, radius = 1.0f; /* firstly, calculate the bone matrix the standard way, since this is needed for roll control */ - BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1); + BKE_pose_where_is_bone(eval_ctx, scene, ob, pchan, ctime, 1); copy_v3_v3(poseHead, pchan->pose_head); copy_v3_v3(poseTail, pchan->pose_tail); @@ -511,7 +516,7 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o } /* Evaluate the chain starting from the nominated bone */ -static void splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime) +static void splineik_execute_tree(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime) { tSplineIK_Tree *tree; @@ -525,7 +530,7 @@ static void splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_ */ for (i = tree->chainlen - 1; i >= 0; i--) { bPoseChannel *pchan = tree->chain[i]; - splineik_evaluate_bone(tree, scene, ob, pchan, i, ctime); + splineik_evaluate_bone(eval_ctx, tree, scene, ob, pchan, i, ctime); } /* free the tree info specific to SplineIK trees now */ @@ -544,14 +549,14 @@ void BKE_pose_splineik_init_tree(Scene *scene, Object *ob, float ctime) splineik_init_tree(scene, ob, ctime); } -void BKE_splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime) +void BKE_splineik_execute_tree(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime) { - splineik_execute_tree(scene, ob, pchan_root, ctime); + splineik_execute_tree(eval_ctx, scene, ob, pchan_root, ctime); } /* *************** Depsgraph evaluation callbacks ************ */ -void BKE_pose_eval_init(struct EvaluationContext *UNUSED(eval_ctx), +void BKE_pose_eval_init(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPose *pose) @@ -576,7 +581,7 @@ void BKE_pose_eval_init(struct EvaluationContext *UNUSED(eval_ctx), } /* 2a. construct the IK tree (standard IK) */ - BIK_initialize_tree(scene, ob, ctime); + BIK_initialize_tree(eval_ctx, scene, ob, ctime); /* 2b. construct the Spline IK trees * - this is not integrated as an IK plugin, since it should be able @@ -585,7 +590,7 @@ void BKE_pose_eval_init(struct EvaluationContext *UNUSED(eval_ctx), BKE_pose_splineik_init_tree(scene, ob, ctime); } -void BKE_pose_eval_bone(struct EvaluationContext *UNUSED(eval_ctx), +void BKE_pose_eval_bone(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan) @@ -613,14 +618,14 @@ void BKE_pose_eval_bone(struct EvaluationContext *UNUSED(eval_ctx), if ((pchan->flag & POSE_DONE) == 0) { /* TODO(sergey): Use time source node for time. */ float ctime = BKE_scene_frame_get(scene); /* not accurate... */ - BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1); + BKE_pose_where_is_bone(eval_ctx, scene, ob, pchan, ctime, 1); } } } } } -void BKE_pose_constraints_evaluate(struct EvaluationContext *UNUSED(eval_ctx), +void BKE_pose_constraints_evaluate(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan) @@ -636,7 +641,7 @@ void BKE_pose_constraints_evaluate(struct EvaluationContext *UNUSED(eval_ctx), else { if ((pchan->flag & POSE_DONE) == 0) { float ctime = BKE_scene_frame_get(scene); /* not accurate... */ - BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1); + BKE_pose_where_is_bone(eval_ctx, scene, ob, pchan, ctime, 1); } } } @@ -652,24 +657,24 @@ void BKE_pose_bone_done(struct EvaluationContext *UNUSED(eval_ctx), } } -void BKE_pose_iktree_evaluate(struct EvaluationContext *UNUSED(eval_ctx), +void BKE_pose_iktree_evaluate(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *rootchan) { float ctime = BKE_scene_frame_get(scene); /* not accurate... */ DEBUG_PRINT("%s on %s pchan %s\n", __func__, ob->id.name, rootchan->name); - BIK_execute_tree(scene, ob, rootchan, ctime); + BIK_execute_tree(eval_ctx, scene, ob, rootchan, ctime); } -void BKE_pose_splineik_evaluate(struct EvaluationContext *UNUSED(eval_ctx), +void BKE_pose_splineik_evaluate(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *rootchan) { float ctime = BKE_scene_frame_get(scene); /* not accurate... */ DEBUG_PRINT("%s on %s pchan %s\n", __func__, ob->id.name, rootchan->name); - BKE_splineik_execute_tree(scene, ob, rootchan, ctime); + BKE_splineik_execute_tree(eval_ctx, scene, ob, rootchan, ctime); } void BKE_pose_eval_flush(struct EvaluationContext *UNUSED(eval_ctx), diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c index 6ac41c72815..09760fcc4cb 100644 --- a/source/blender/blenkernel/intern/blendfile.c +++ b/source/blender/blenkernel/intern/blendfile.c @@ -218,6 +218,13 @@ static void setup_app_data( BKE_screen_view3d_scene_sync(curscreen, curscene); } } + + /* We need to tag this here because events may be handled immediately after. + * only the current screen is important because we wont have to handle + * events from multiple screens at once.*/ + { + BKE_screen_manipulator_tag_refresh(curscreen); + } } /* free G.main Main database */ @@ -332,11 +339,20 @@ static void setup_app_data( } } } + + /* Setting scene might require having a dependency graph, with copy on write + * we need to make sure we ensure scene has correct color management before + * constructing dependency graph. + */ + if (mode != LOAD_UNDO) { + IMB_colormanagement_check_file_config(G.main); + } + BKE_scene_set_background(G.main, curscene); if (mode != LOAD_UNDO) { + /* TODO(sergey): Can this be also move above? */ RE_FreeAllPersistentData(); - IMB_colormanagement_check_file_config(G.main); } MEM_freeN(bfd); diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 7ca4e07076d..8c78787c259 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -132,6 +132,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, if (eff == NULL && gabr->ob) { memset(&temp_eff, 0, sizeof(EffectorCache)); temp_eff.ob = gabr->ob; + temp_eff.eval_ctx = bbd->sim->eval_ctx; temp_eff.scene = bbd->sim->scene; eff = &temp_eff; get_effector_data(eff, &efd, &epoint, 0); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 6d0ad3255a2..05e92613c62 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -345,7 +345,7 @@ static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul return 1; } -static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr) +static int do_step_cloth(struct EvaluationContext *eval_ctx, Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr) { ClothVertex *verts = NULL; Cloth *cloth; @@ -370,7 +370,7 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul mul_m4_v3(ob->obmat, verts->xconst); } - effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights, true); + effectors = pdInitEffectors(eval_ctx, clmd->scene, ob, NULL, clmd->sim_parms->effector_weights, true); if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH ) cloth_update_verts ( ob, clmd, result ); @@ -400,7 +400,7 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul /************************************************ * clothModifier_do - main simulation function ************************************************/ -void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3]) +void clothModifier_do(ClothModifierData *clmd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3]) { PointCache *cache; PTCacheID pid; @@ -489,7 +489,7 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived /* do simulation */ BKE_ptcache_validate(cache, framenr); - if (!do_step_cloth(ob, clmd, dm, framenr)) { + if (!do_step_cloth(eval_ctx, ob, clmd, dm, framenr)) { BKE_ptcache_invalidate(cache); } else diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 38534f03123..2b69c176c39 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -261,6 +261,9 @@ void BKE_collection_object_add_from(Scene *scene, Object *ob_src, Object *ob_dst for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) { Base *base_src = BKE_scene_layer_base_find(sl, ob_src); if (base_src != NULL) { + if (base_src->collection_properties == NULL) { + continue; + } Base *base_dst = BKE_scene_layer_base_find(sl, ob_dst); IDP_MergeGroup(base_dst->collection_properties, base_src->collection_properties, true); } diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 07a6b304dff..ac7168b6561 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -689,7 +689,7 @@ static bConstraintTypeInfo CTI_CONSTRNAME = { /* This function should be used for the get_target_matrix member of all * constraints that are not picky about what happens to their target matrix. */ -static void default_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime)) +static void default_get_tarmat(struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime)) { if (VALID_CONS_TARGET(ct)) constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->flag, con->headtail); @@ -1155,7 +1155,7 @@ static void kinematic_flush_tars(bConstraint *con, ListBase *list, bool no_copy) } } -static void kinematic_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) +static void kinematic_get_tarmat(struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) { bKinematicConstraint *data = con->data; @@ -1242,7 +1242,7 @@ static void followpath_flush_tars(bConstraint *con, ListBase *list, bool no_copy } } -static void followpath_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) +static void followpath_get_tarmat(struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) { bFollowPathConstraint *data = con->data; @@ -1259,7 +1259,7 @@ static void followpath_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra #ifdef CYCLIC_DEPENDENCY_WORKAROUND if (ct->tar->curve_cache == NULL) { - BKE_displist_make_curveTypes(cob->scene, ct->tar, false); + BKE_displist_make_curveTypes(eval_ctx, cob->scene, ct->tar, false); } #endif @@ -2024,7 +2024,7 @@ static void pycon_id_looper(bConstraint *con, ConstraintIDFunc func, void *userd } /* Whether this approach is maintained remains to be seen (aligorith) */ -static void pycon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) +static void pycon_get_tarmat(struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) { #ifdef WITH_PYTHON bPythonConstraint *data = con->data; @@ -2035,7 +2035,7 @@ static void pycon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTa /* special exception for curves - depsgraph issues */ if (ct->tar->type == OB_CURVE) { if (ct->tar->curve_cache == NULL) { - BKE_displist_make_curveTypes(cob->scene, ct->tar, false); + BKE_displist_make_curveTypes(eval_ctx, cob->scene, ct->tar, false); } } #endif @@ -2142,7 +2142,7 @@ static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy) } } -static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) +static void actcon_get_tarmat(struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) { bActionConstraint *data = con->data; @@ -3131,12 +3131,12 @@ static void clampto_flush_tars(bConstraint *con, ListBase *list, bool no_copy) } } -static void clampto_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) +static void clampto_get_tarmat(struct EvaluationContext *eval_ctx, bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) { #ifdef CYCLIC_DEPENDENCY_WORKAROUND if (VALID_CONS_TARGET(ct)) { if (ct->tar->curve_cache == NULL) { - BKE_displist_make_curveTypes(cob->scene, ct->tar, false); + BKE_displist_make_curveTypes(eval_ctx, cob->scene, ct->tar, false); } } #endif @@ -3474,7 +3474,7 @@ static void shrinkwrap_flush_tars(bConstraint *con, ListBase *list, bool no_copy } -static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) +static void shrinkwrap_get_tarmat(struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) { bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *) con->data; @@ -3806,12 +3806,12 @@ static void splineik_flush_tars(bConstraint *con, ListBase *list, bool no_copy) } } -static void splineik_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) +static void splineik_get_tarmat(struct EvaluationContext *eval_ctx, bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) { #ifdef CYCLIC_DEPENDENCY_WORKAROUND if (VALID_CONS_TARGET(ct)) { if (ct->tar->curve_cache == NULL) { - BKE_displist_make_curveTypes(cob->scene, ct->tar, false); + BKE_displist_make_curveTypes(eval_ctx, cob->scene, ct->tar, false); } } #endif @@ -4858,7 +4858,7 @@ bool BKE_constraints_proxylocked_owner(Object *ob, bPoseChannel *pchan) * None of the actual calculations of the matrices should be done here! Also, this function is * not to be used by any new constraints, particularly any that have multiple targets. */ -void BKE_constraint_target_matrix_get(Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime) +void BKE_constraint_target_matrix_get(struct EvaluationContext *eval_ctx, Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime) { const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; @@ -4909,7 +4909,7 @@ void BKE_constraint_target_matrix_get(Scene *scene, bConstraint *con, int index, if (ct) { if (cti->get_target_matrix) - cti->get_target_matrix(con, cob, ct, ctime); + cti->get_target_matrix(eval_ctx, con, cob, ct, ctime); copy_m4_m4(mat, ct->matrix); } @@ -4925,7 +4925,7 @@ void BKE_constraint_target_matrix_get(Scene *scene, bConstraint *con, int index, } /* Get the list of targets required for solving a constraint */ -void BKE_constraint_targets_for_solving_get(bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime) +void BKE_constraint_targets_for_solving_get(struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime) { const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); @@ -4943,7 +4943,7 @@ void BKE_constraint_targets_for_solving_get(bConstraint *con, bConstraintOb *cob */ if (cti->get_target_matrix) { for (ct = targets->first; ct; ct = ct->next) - cti->get_target_matrix(con, cob, ct, ctime); + cti->get_target_matrix(eval_ctx, con, cob, ct, ctime); } else { for (ct = targets->first; ct; ct = ct->next) @@ -4960,7 +4960,7 @@ void BKE_constraint_targets_for_solving_get(bConstraint *con, bConstraintOb *cob * BKE_constraints_make_evalob and BKE_constraints_clear_evalob should be called before and * after running this function, to sort out cob */ -void BKE_constraints_solve(ListBase *conlist, bConstraintOb *cob, float ctime) +void BKE_constraints_solve(struct EvaluationContext *eval_ctx, ListBase *conlist, bConstraintOb *cob, float ctime) { bConstraint *con; float oldmat[4][4]; @@ -4995,7 +4995,7 @@ void BKE_constraints_solve(ListBase *conlist, bConstraintOb *cob, float ctime) BKE_constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace, false); /* prepare targets for constraint solving */ - BKE_constraint_targets_for_solving_get(con, cob, &targets, ctime); + BKE_constraint_targets_for_solving_get(eval_ctx, con, cob, &targets, ctime); /* Solve the constraint and put result in cob->matrix */ cti->evaluate_constraint(con, cob, &targets); diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 8cb9fb3fad5..d301ff56876 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -77,6 +77,7 @@ struct bContext { struct ScrArea *area; struct ARegion *region; struct ARegion *menu; + struct wmManipulatorGroup *manipulator_group; struct bContextStore *store; const char *operator_poll_msg; /* reason for poll failing */ } wm; @@ -671,6 +672,11 @@ struct ARegion *CTX_wm_menu(const bContext *C) return C->wm.menu; } +struct wmManipulatorGroup *CTX_wm_manipulator_group(const bContext *C) +{ + return C->wm.manipulator_group; +} + struct ReportList *CTX_wm_reports(const bContext *C) { if (C->wm.manager) @@ -870,6 +876,11 @@ void CTX_wm_menu_set(bContext *C, ARegion *menu) C->wm.menu = menu; } +void CTX_wm_manipulator_group_set(bContext *C, struct wmManipulatorGroup *mgroup) +{ + C->wm.manipulator_group = mgroup; +} + void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg) { C->wm.operator_poll_msg = msg; @@ -916,7 +927,7 @@ SceneLayer *CTX_data_scene_layer(const bContext *C) return sl; } else { - return BKE_scene_layer_context_active_ex_PLACEHOLDER(CTX_data_main(C), CTX_data_scene(C)); + return BKE_scene_layer_from_workspace_get(CTX_wm_workspace(C)); } } @@ -1231,3 +1242,14 @@ Depsgraph *CTX_data_depsgraph(const bContext *C) SceneLayer *scene_layer = CTX_data_scene_layer(C); return BKE_scene_get_depsgraph(scene, scene_layer); } + +void CTX_data_eval_ctx(const bContext *C, EvaluationContext *eval_ctx) +{ + BLI_assert(C != NULL); + + Scene *scene = CTX_data_scene(C); + SceneLayer *scene_layer = CTX_data_scene_layer(C); + DEG_evaluation_context_init_from_scene(eval_ctx, + scene, scene_layer, + DAG_EVAL_VIEWPORT); +} diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c index 56df8e51eba..da05c05a694 100644 --- a/source/blender/blenkernel/intern/crazyspace.c +++ b/source/blender/blenkernel/intern/crazyspace.c @@ -99,7 +99,7 @@ static int modifiers_disable_subsurf_temporary(Object *ob) } /* disable subsurf temporal, get mapped cos, and enable it */ -float (*BKE_crazyspace_get_mapped_editverts(Scene *scene, Object *obedit))[3] +float (*BKE_crazyspace_get_mapped_editverts(struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit))[3] { Mesh *me = obedit->data; DerivedMesh *dm; @@ -109,13 +109,13 @@ float (*BKE_crazyspace_get_mapped_editverts(Scene *scene, Object *obedit))[3] /* disable subsurf temporal, get mapped cos, and enable it */ if (modifiers_disable_subsurf_temporary(obedit)) { /* need to make new derivemesh */ - makeDerivedMesh(scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH, false); + makeDerivedMesh(eval_ctx, scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH, false); } /* now get the cage */ vertexcos = MEM_mallocN(sizeof(*vertexcos) * nverts, "vertexcos map"); - dm = editbmesh_get_derived_cage(scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH); + dm = editbmesh_get_derived_cage(eval_ctx, scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH); mesh_get_mapped_verts_coords(dm, vertexcos, nverts); @@ -250,7 +250,7 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me, float (*origcos)[3], float (*mapped /** returns an array of deform matrices for crazyspace correction, and the * number of modifiers left */ -int BKE_crazyspace_get_first_deform_matrices_editbmesh(Scene *scene, Object *ob, BMEditMesh *em, +int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BMEditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3]) { ModifierData *md; @@ -290,7 +290,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(Scene *scene, Object *ob, unit_m3(defmats[a]); } - mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats, + mti->deformMatricesEM(md, eval_ctx, ob, em, dm, deformedVerts, defmats, numVerts); } else @@ -310,7 +310,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(Scene *scene, Object *ob, return numleft; } -int BKE_sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]) +int BKE_sculpt_get_first_deform_matrices(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]) { ModifierData *md; DerivedMesh *dm; @@ -346,7 +346,7 @@ int BKE_sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**defo unit_m3(defmats[a]); } - if (mti->deformMatrices) mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts); + if (mti->deformMatrices) mti->deformMatrices(md, eval_ctx, ob, dm, deformedVerts, defmats, numVerts); else break; } } @@ -369,9 +369,9 @@ int BKE_sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**defo return numleft; } -void BKE_crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]) +void BKE_crazyspace_build_sculpt(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]) { - int totleft = BKE_sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos); + int totleft = BKE_sculpt_get_first_deform_matrices(eval_ctx, scene, ob, deformmats, deformcos); if (totleft) { /* there are deformation modifier which doesn't support deformation matrices @@ -396,7 +396,7 @@ void BKE_crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[ if (mti->deformMatrices && !deformed) continue; - mti->deformVerts(md, ob, NULL, deformedVerts, me->totvert, 0); + mti->deformVerts(md, eval_ctx, ob, NULL, deformedVerts, me->totvert, 0); deformed = 1; } } diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 2863a925000..6018c07835b 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1625,7 +1625,7 @@ float *BKE_curve_surf_make_orco(Object *ob) /* NOTE: This routine is tied to the order of vertex * built by displist and as passed to the renderer. */ -float *BKE_curve_make_orco(Scene *scene, Object *ob, int *r_numVerts) +float *BKE_curve_make_orco(EvaluationContext *eval_ctx, Scene *scene, Object *ob, int *r_numVerts) { Curve *cu = ob->data; DispList *dl; @@ -1633,7 +1633,7 @@ float *BKE_curve_make_orco(Scene *scene, Object *ob, int *r_numVerts) float *fp, *coord_array; ListBase disp = {NULL, NULL}; - BKE_displist_make_curveTypes_forOrco(scene, ob, &disp); + BKE_displist_make_curveTypes_forOrco(eval_ctx, scene, ob, &disp); numVerts = 0; for (dl = disp.first; dl; dl = dl->next) { @@ -1724,7 +1724,7 @@ float *BKE_curve_make_orco(Scene *scene, Object *ob, int *r_numVerts) /* ***************** BEVEL ****************** */ -void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, +void BKE_curve_bevel_make(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *disp, const bool for_render, const bool use_render_resolution) { DispList *dl, *dlnew; @@ -1749,7 +1749,7 @@ void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, facy = cu->bevobj->size[1]; if (for_render) { - BKE_displist_make_curveTypes_forRender(scene, cu->bevobj, &bevdisp, NULL, false, use_render_resolution); + BKE_displist_make_curveTypes_forRender(eval_ctx, scene, cu->bevobj, &bevdisp, NULL, false, use_render_resolution); dl = bevdisp.first; } else if (cu->bevobj->curve_cache) { @@ -4706,4 +4706,4 @@ void BKE_curve_batch_cache_free(Curve *cu) if (cu->batch_cache) { BKE_curve_batch_cache_free_cb(cu); } -}
\ No newline at end of file +} diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c index a83ec8f0486..0b88cc48a96 100644 --- a/source/blender/blenkernel/intern/data_transfer.c +++ b/source/blender/blenkernel/intern/data_transfer.c @@ -1010,7 +1010,7 @@ static bool data_transfer_layersmapping_generate( * to get (as much as possible) exact copy of source data layout. */ void BKE_object_data_transfer_layout( - Scene *scene, Object *ob_src, Object *ob_dst, const int data_types, const bool use_delete, + struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, const int data_types, const bool use_delete, const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX]) { DerivedMesh *dm_src; @@ -1027,7 +1027,7 @@ void BKE_object_data_transfer_layout( /* Get source DM.*/ dm_src_mask |= BKE_object_data_transfer_dttypes_to_cdmask(data_types); - dm_src = mesh_get_derived_final(scene, ob_src, dm_src_mask); + dm_src = mesh_get_derived_final(eval_ctx, scene, ob_src, dm_src_mask); if (!dm_src) { return; } @@ -1085,9 +1085,9 @@ void BKE_object_data_transfer_layout( } bool BKE_object_data_transfer_dm( - Scene *scene, Object *ob_src, Object *ob_dst, DerivedMesh *dm_dst, const int data_types, bool use_create, - const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode, - SpaceTransform *space_transform, const bool auto_transform, + struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, DerivedMesh *dm_dst, + const int data_types, bool use_create, const int map_vert_mode, const int map_edge_mode, + const int map_loop_mode, const int map_poly_mode, SpaceTransform *space_transform, const bool auto_transform, const float max_distance, const float ray_radius, const float islands_handling_precision, const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX], const int mix_mode, const float mix_factor, const char *vgroup_name, const bool invert_vgroup, @@ -1149,7 +1149,7 @@ bool BKE_object_data_transfer_dm( * Also, we need to make a local copy of dm_src, otherwise we may end with concurrent creation * of data in it (multi-threaded evaluation of the modifier stack, see T46672). */ - dm_src = dm_dst ? ob_src->derivedFinal : mesh_get_derived_final(scene, ob_src, dm_src_mask); + dm_src = dm_dst ? ob_src->derivedFinal : mesh_get_derived_final(eval_ctx, scene, ob_src, dm_src_mask); if (!dm_src) { return changed; } @@ -1457,16 +1457,16 @@ bool BKE_object_data_transfer_dm( } bool BKE_object_data_transfer_mesh( - Scene *scene, Object *ob_src, Object *ob_dst, const int data_types, const bool use_create, - const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode, - SpaceTransform *space_transform, const bool auto_transform, + struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, const int data_types, + const bool use_create, const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, + const int map_poly_mode, SpaceTransform *space_transform, const bool auto_transform, const float max_distance, const float ray_radius, const float islands_handling_precision, const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX], const int mix_mode, const float mix_factor, const char *vgroup_name, const bool invert_vgroup, ReportList *reports) { return BKE_object_data_transfer_dm( - scene, ob_src, ob_dst, NULL, data_types, use_create, + eval_ctx, scene, ob_src, ob_dst, NULL, data_types, use_create, map_vert_mode, map_edge_mode, map_loop_mode, map_poly_mode, space_transform, auto_transform, max_distance, ray_radius, islands_handling_precision, diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index ffe9986d166..584942628fa 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -624,8 +624,17 @@ float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup) */ float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup) { - if (defgroup == -1 || dvert == NULL) + /* Invalid defgroup index means the vgroup selected is invalid, does not exist, in that case it is OK to return 1.0 + * (i.e. maximum weight, as if no vgroup was selected). + * But in case of valid defgroup and NULL dvert data pointer, it means that vgroup **is** valid, + * and just totally empty, so we shall return '0.0' value then! + */ + if (defgroup == -1) { return 1.0f; + } + else if (dvert == NULL) { + return 0.0f; + } return defvert_find_weight(dvert + index, defgroup); } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 25f50056c42..fd22aaa291b 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -678,7 +678,7 @@ static void curve_to_filledpoly(Curve *cu, ListBase *UNUSED(nurb), ListBase *dis * - first point left, last point right * - based on subdivided points in original curve, not on points in taper curve (still) */ -static float displist_calc_taper(Scene *scene, Object *taperobj, float fac) +static float displist_calc_taper(EvaluationContext *eval_ctx, Scene *scene, Object *taperobj, float fac) { DispList *dl; @@ -687,7 +687,7 @@ static float displist_calc_taper(Scene *scene, Object *taperobj, float fac) dl = taperobj->curve_cache ? taperobj->curve_cache->disp.first : NULL; if (dl == NULL) { - BKE_displist_make_curveTypes(scene, taperobj, 0); + BKE_displist_make_curveTypes(eval_ctx, scene, taperobj, 0); dl = taperobj->curve_cache->disp.first; } if (dl) { @@ -718,11 +718,11 @@ static float displist_calc_taper(Scene *scene, Object *taperobj, float fac) return 1.0; } -float BKE_displist_calc_taper(Scene *scene, Object *taperobj, int cur, int tot) +float BKE_displist_calc_taper(EvaluationContext *eval_ctx, Scene *scene, Object *taperobj, int cur, int tot) { float fac = ((float)cur) / (float)(tot - 1); - return displist_calc_taper(scene, taperobj, fac); + return displist_calc_taper(eval_ctx, scene, taperobj, fac); } void BKE_displist_make_mball(EvaluationContext *eval_ctx, Scene *scene, Object *ob) @@ -798,7 +798,7 @@ static ModifierData *curve_get_tessellate_point(Scene *scene, Object *ob, return pretessellatePoint; } -static void curve_calc_modifiers_pre(Scene *scene, Object *ob, ListBase *nurb, +static void curve_calc_modifiers_pre(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *nurb, const bool for_render, const bool use_render_resolution) { VirtualModifierData virtualModifierData; @@ -856,7 +856,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, ListBase *nurb, deformedVerts = BKE_curve_nurbs_vertexCos_get(nurb, &numVerts); } - mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, app_flag); + mti->deformVerts(md, eval_ctx, ob, NULL, deformedVerts, numVerts, app_flag); if (md == pretessellatePoint) break; @@ -908,7 +908,7 @@ static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3]) } } -static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *nurb, +static void curve_calc_modifiers_post(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *nurb, ListBase *dispbase, DerivedMesh **r_dm_final, const bool for_render, const bool use_render_resolution) { @@ -964,14 +964,14 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *nurb, dm->getVertCos(dm, vertCos); } - mti->deformVerts(md, ob, dm, vertCos, totvert, appf); + mti->deformVerts(md, eval_ctx, ob, dm, vertCos, totvert, appf); } else { if (!vertCos) { vertCos = displist_get_allverts(dispbase, &totvert); } - mti->deformVerts(md, ob, NULL, vertCos, totvert, appf); + mti->deformVerts(md, eval_ctx, ob, NULL, vertCos, totvert, appf); } } else { @@ -1013,7 +1013,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *nurb, if (useCache) appf |= MOD_APPLY_USECACHE; - ndm = modwrap_applyModifier(md, ob, dm, appf); + ndm = modwrap_applyModifier(md, eval_ctx, ob, dm, appf); if (ndm) { /* Modifier returned a new derived mesh */ @@ -1090,13 +1090,13 @@ static void displist_surf_indices(DispList *dl) } } -static DerivedMesh *create_orco_dm(Scene *scene, Object *ob) +static DerivedMesh *create_orco_dm(EvaluationContext *eval_ctx, Scene *scene, Object *ob) { DerivedMesh *dm; ListBase disp = {NULL, NULL}; /* OrcoDM should be created from underformed disp lists */ - BKE_displist_make_curveTypes_forOrco(scene, ob, &disp); + BKE_displist_make_curveTypes_forOrco(eval_ctx, scene, ob, &disp); dm = CDDM_from_curve_displist(ob, &disp); BKE_displist_free(&disp); @@ -1134,7 +1134,7 @@ static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm) DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco); } -static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *dm_final, +static void curve_calc_orcodm(EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm_final, const bool for_render, const bool use_render_resolution) { /* this function represents logic of mesh's orcodm calculation @@ -1172,7 +1172,7 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *dm_final, * This means we can create ORCO DM in advance and assume it's * never NULL. */ - orcodm = create_orco_dm(scene, ob); + orcodm = create_orco_dm(eval_ctx, scene, ob); for (; md; md = md->next) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); @@ -1184,7 +1184,7 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *dm_final, if (mti->type != eModifierTypeType_Constructive) continue; - ndm = modwrap_applyModifier(md, ob, orcodm, app_flag); + ndm = modwrap_applyModifier(md, eval_ctx, ob, orcodm, app_flag); if (ndm) { /* if the modifier returned a new dm, release the old one */ @@ -1201,7 +1201,7 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *dm_final, orcodm->release(orcodm); } -void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase, +void BKE_displist_make_surf(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase, DerivedMesh **r_dm_final, const bool for_render, const bool for_orco, const bool use_render_resolution) { @@ -1220,7 +1220,7 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase, } if (!for_orco) - curve_calc_modifiers_pre(scene, ob, &nubase, for_render, use_render_resolution); + curve_calc_modifiers_pre(eval_ctx, scene, ob, &nubase, for_render, use_render_resolution); for (nu = nubase.first; nu; nu = nu->next) { if ((for_render || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) { @@ -1287,7 +1287,7 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase, if (!for_orco) { BKE_nurbList_duplicate(&ob->curve_cache->deformed_nurbs, &nubase); - curve_calc_modifiers_post(scene, ob, &nubase, dispbase, r_dm_final, + curve_calc_modifiers_post(eval_ctx, scene, ob, &nubase, dispbase, r_dm_final, for_render, use_render_resolution); } @@ -1513,7 +1513,7 @@ static void calc_bevfac_mapping(Curve *cu, BevList *bl, Nurb *nu, } } -static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase, +static void do_makeDispListCurveTypes(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase, DerivedMesh **r_dm_final, const bool for_render, const bool for_orco, const bool use_render_resolution) { @@ -1523,7 +1523,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba if (!ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return; if (ob->type == OB_SURF) { - BKE_displist_make_surf(scene, ob, dispbase, r_dm_final, for_render, for_orco, use_render_resolution); + BKE_displist_make_surf(eval_ctx, scene, ob, dispbase, r_dm_final, for_render, for_orco, use_render_resolution); } else if (ELEM(ob->type, OB_CURVE, OB_FONT)) { ListBase dlbev; @@ -1548,12 +1548,12 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba } if (!for_orco) - curve_calc_modifiers_pre(scene, ob, &nubase, for_render, use_render_resolution); + curve_calc_modifiers_pre(eval_ctx, scene, ob, &nubase, for_render, use_render_resolution); BKE_curve_bevelList_make(ob, &nubase, for_render != false); /* If curve has no bevel will return nothing */ - BKE_curve_bevel_make(scene, ob, &dlbev, for_render, use_render_resolution); + BKE_curve_bevel_make(eval_ctx, scene, ob, &dlbev, for_render, use_render_resolution); /* no bevel or extrude, and no width correction? */ if (!dlbev.first && cu->width == 1.0f) { @@ -1688,7 +1688,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba taper_fac -= (1.0f - lastblend) / len; } - fac = displist_calc_taper(scene, cu->taperobj, taper_fac); + fac = displist_calc_taper(eval_ctx, scene, cu->taperobj, taper_fac); } if (bevp->split_tag) { @@ -1750,7 +1750,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba if (!for_orco) { BKE_nurbList_duplicate(&ob->curve_cache->deformed_nurbs, &nubase); - curve_calc_modifiers_post(scene, ob, &nubase, dispbase, r_dm_final, for_render, use_render_resolution); + curve_calc_modifiers_post(eval_ctx, scene, ob, &nubase, dispbase, r_dm_final, for_render, use_render_resolution); } if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) { @@ -1761,7 +1761,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba } } -void BKE_displist_make_curveTypes(Scene *scene, Object *ob, const bool for_orco) +void BKE_displist_make_curveTypes(EvaluationContext *eval_ctx, Scene *scene, Object *ob, const bool for_orco) { ListBase *dispbase; @@ -1779,12 +1779,12 @@ void BKE_displist_make_curveTypes(Scene *scene, Object *ob, const bool for_orco) dispbase = &(ob->curve_cache->disp); - do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, for_orco, 0); + do_makeDispListCurveTypes(eval_ctx, scene, ob, dispbase, &ob->derivedFinal, 0, for_orco, 0); boundbox_displist_object(ob); } -void BKE_displist_make_curveTypes_forRender(Scene *scene, Object *ob, ListBase *dispbase, +void BKE_displist_make_curveTypes_forRender(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase, DerivedMesh **r_dm_final, const bool for_orco, const bool use_render_resolution) { @@ -1792,20 +1792,20 @@ void BKE_displist_make_curveTypes_forRender(Scene *scene, Object *ob, ListBase * ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); } - do_makeDispListCurveTypes(scene, ob, dispbase, r_dm_final, true, for_orco, use_render_resolution); + do_makeDispListCurveTypes(eval_ctx, scene, ob, dispbase, r_dm_final, true, for_orco, use_render_resolution); } -void BKE_displist_make_curveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase) +void BKE_displist_make_curveTypes_forOrco(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase) { if (ob->curve_cache == NULL) { ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); } - do_makeDispListCurveTypes(scene, ob, dispbase, NULL, 1, 1, 1); + do_makeDispListCurveTypes(eval_ctx, scene, ob, dispbase, NULL, 1, 1, 1); } /* add Orco layer to the displist object which has got derived mesh and return orco */ -float *BKE_displist_make_orco(Scene *scene, Object *ob, DerivedMesh *dm_final, +float *BKE_displist_make_orco(EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm_final, const bool for_render, const bool use_render_resolution) { @@ -1815,7 +1815,7 @@ float *BKE_displist_make_orco(Scene *scene, Object *ob, DerivedMesh *dm_final, dm_final = ob->derivedFinal; if (!dm_final->getVertDataArray(dm_final, CD_ORCO)) { - curve_calc_orcodm(scene, ob, dm_final, for_render, use_render_resolution); + curve_calc_orcodm(eval_ctx, scene, ob, dm_final, for_render, use_render_resolution); } orco = dm_final->getVertDataArray(dm_final, CD_ORCO); diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index fb5ef403218..6ac284d6b73 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -74,6 +74,8 @@ #include "BKE_scene.h" #include "BKE_texture.h" +#include "DEG_depsgraph.h" + /* for image output */ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -1973,7 +1975,7 @@ static void canvas_copyDerivedMesh(DynamicPaintCanvasSettings *canvas, DerivedMe /* * Updates derived mesh copy and processes dynamic paint step / caches. */ -static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene, SceneLayer *sl, Object *ob, DerivedMesh *dm) +static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm) { if (pmd->canvas) { DynamicPaintCanvasSettings *canvas = pmd->canvas; @@ -2036,7 +2038,7 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene else if (can_simulate) { /* calculate surface frame */ canvas->flags |= MOD_DPAINT_BAKING; - dynamicPaint_calculateFrame(surface, scene, sl, ob, current_frame); + dynamicPaint_calculateFrame(surface, eval_ctx, scene, ob, current_frame); canvas->flags &= ~MOD_DPAINT_BAKING; /* restore canvas derivedmesh if required */ @@ -2055,7 +2057,7 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene } /* Modifier call. Processes dynamic paint modifier step. */ -DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Scene *scene, SceneLayer *sl, Object *ob, DerivedMesh *dm) +DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm) { if (pmd->canvas) { DerivedMesh *ret; @@ -2064,7 +2066,7 @@ DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Scene *scen DM_ensure_looptri(dm); /* Update canvas data for a new frame */ - dynamicPaint_frameUpdate(pmd, scene, sl, ob, dm); + dynamicPaint_frameUpdate(pmd, eval_ctx, scene, ob, dm); /* Return output mesh */ ret = dynamicPaint_Modifier_apply(pmd, ob, dm); @@ -2076,7 +2078,7 @@ DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Scene *scen DM_ensure_looptri(dm); /* Update canvas data for a new frame */ - dynamicPaint_frameUpdate(pmd, scene, sl, ob, dm); + dynamicPaint_frameUpdate(pmd, eval_ctx, scene, ob, dm); /* Return output mesh */ return dynamicPaint_Modifier_apply(pmd, ob, dm); @@ -3582,7 +3584,7 @@ static void dynamic_paint_brush_velocity_compute_cb(void *userdata, const int i) } static void dynamicPaint_brushMeshCalculateVelocity( - Scene *scene, Object *ob, DynamicPaintBrushSettings *brush, Vec3f **brushVel, float timescale) + struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DynamicPaintBrushSettings *brush, Vec3f **brushVel, float timescale) { float prev_obmat[4][4]; DerivedMesh *dm_p, *dm_c; @@ -3604,7 +3606,7 @@ static void dynamicPaint_brushMeshCalculateVelocity( scene->r.subframe = prev_sfra; BKE_object_modifier_update_subframe( - scene, ob, true, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); + eval_ctx, scene, ob, true, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); dm_p = CDDM_copy(brush->dm); numOfVerts_p = dm_p->getNumVerts(dm_p); mvert_p = dm_p->getVertArray(dm_p); @@ -3615,7 +3617,7 @@ static void dynamicPaint_brushMeshCalculateVelocity( scene->r.subframe = cur_sfra; BKE_object_modifier_update_subframe( - scene, ob, true, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); + eval_ctx, scene, ob, true, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); dm_c = brush->dm; numOfVerts_c = dm_c->getNumVerts(dm_c); mvert_c = dm_p->getVertArray(dm_c); @@ -3640,7 +3642,7 @@ static void dynamicPaint_brushMeshCalculateVelocity( } /* calculate velocity for object center point */ -static void dynamicPaint_brushObjectCalculateVelocity(Scene *scene, Object *ob, Vec3f *brushVel, float timescale) +static void dynamicPaint_brushObjectCalculateVelocity(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Vec3f *brushVel, float timescale) { float prev_obmat[4][4]; float cur_loc[3] = {0.0f}, prev_loc[3] = {0.0f}; @@ -3659,14 +3661,14 @@ static void dynamicPaint_brushObjectCalculateVelocity(Scene *scene, Object *ob, scene->r.cfra = prev_fra; scene->r.subframe = prev_sfra; BKE_object_modifier_update_subframe( - scene, ob, false, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); + eval_ctx, scene, ob, false, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); copy_m4_m4(prev_obmat, ob->obmat); /* current frame dm */ scene->r.cfra = cur_fra; scene->r.subframe = cur_sfra; BKE_object_modifier_update_subframe( - scene, ob, false, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); + eval_ctx, scene, ob, false, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); /* calculate speed */ mul_m4_v3(prev_obmat, prev_loc); @@ -4036,7 +4038,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex( } } -static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, +static int dynamicPaint_paintMesh(struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface, DynamicPaintBrushSettings *brush, Object *brushOb, BrushMaterials *bMats, @@ -4052,7 +4054,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, const MLoop *mloop = NULL; if (brush->flags & MOD_DPAINT_USES_VELOCITY) - dynamicPaint_brushMeshCalculateVelocity(scene, brushOb, brush, &brushVelocity, timescale); + dynamicPaint_brushMeshCalculateVelocity(eval_ctx, scene, brushOb, brush, &brushVelocity, timescale); if (!brush->dm) return 0; @@ -4530,7 +4532,7 @@ static void dynamic_paint_paint_single_point_cb_ex( } static int dynamicPaint_paintSinglePoint( - DynamicPaintSurface *surface, float *pointCoord, DynamicPaintBrushSettings *brush, + struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface, float *pointCoord, DynamicPaintBrushSettings *brush, Object *brushOb, BrushMaterials *bMats, Scene *scene, float timescale) { PaintSurfaceData *sData = surface->data; @@ -4538,7 +4540,7 @@ static int dynamicPaint_paintSinglePoint( Vec3f brushVel; if (brush->flags & MOD_DPAINT_USES_VELOCITY) - dynamicPaint_brushObjectCalculateVelocity(scene, brushOb, &brushVel, timescale); + dynamicPaint_brushObjectCalculateVelocity(eval_ctx, scene, brushOb, &brushVel, timescale); const MVert *mvert = brush->dm->getVertArray(brush->dm); @@ -4845,7 +4847,7 @@ static void dynamic_paint_prepare_effect_cb(void *userdata, const int index) } static int dynamicPaint_prepareEffectStep( - DynamicPaintSurface *surface, Scene *scene, Object *ob, float **force, float timescale) + struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface, Scene *scene, Object *ob, float **force, float timescale) { double average_force = 0.0f; float shrink_speed = 0.0f, spread_speed = 0.0f; @@ -4856,7 +4858,7 @@ static int dynamicPaint_prepareEffectStep( /* Init force data if required */ if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) { - ListBase *effectors = pdInitEffectors(scene, ob, NULL, surface->effector_weights, true); + ListBase *effectors = pdInitEffectors(eval_ctx, scene, ob, NULL, surface->effector_weights, true); /* allocate memory for force data (dir vector + strength) */ *force = MEM_mallocN(sData->total_points * 4 * sizeof(float), "PaintEffectForces"); @@ -5758,7 +5760,7 @@ static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface, const Sce /* * Do Dynamic Paint step. Paints scene brush objects of current state/frame to the surface. */ -static int dynamicPaint_doStep(Scene *scene, SceneLayer *sl, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe) +static int dynamicPaint_doStep(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe) { PaintSurfaceData *sData = surface->data; PaintBakeData *bData = sData->bData; @@ -5782,6 +5784,7 @@ static int dynamicPaint_doStep(Scene *scene, SceneLayer *sl, Object *ob, Dynamic GroupObject *go = NULL; Object *brushObj = NULL; ModifierData *md = NULL; + SceneLayer *sl = eval_ctx->scene_layer; /* backup current scene frame */ int scene_frame = scene->r.cfra; @@ -5836,7 +5839,7 @@ static int dynamicPaint_doStep(Scene *scene, SceneLayer *sl, Object *ob, Dynamic /* update object data on this subframe */ if (subframe) { scene_setSubframe(scene, subframe); - BKE_object_modifier_update_subframe(scene, brushObj, true, SUBFRAME_RECURSION, + BKE_object_modifier_update_subframe(eval_ctx, scene, brushObj, true, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); } /* Prepare materials if required */ @@ -5855,11 +5858,11 @@ static int dynamicPaint_doStep(Scene *scene, SceneLayer *sl, Object *ob, Dynamic } /* Object center distance: */ if (brush->collision == MOD_DPAINT_COL_POINT && brushObj != ob) { - dynamicPaint_paintSinglePoint(surface, brushObj->loc, brush, brushObj, &bMats, scene, timescale); + dynamicPaint_paintSinglePoint(eval_ctx, surface, brushObj->loc, brush, brushObj, &bMats, scene, timescale); } /* Mesh volume/proximity: */ else if (brushObj != ob) { - dynamicPaint_paintMesh(surface, brush, brushObj, &bMats, scene, timescale); + dynamicPaint_paintMesh(eval_ctx, surface, brush, brushObj, &bMats, scene, timescale); } /* free temp material data */ @@ -5869,7 +5872,7 @@ static int dynamicPaint_doStep(Scene *scene, SceneLayer *sl, Object *ob, Dynamic if (subframe) { scene->r.cfra = scene_frame; scene->r.subframe = scene_subframe; - BKE_object_modifier_update_subframe(scene, brushObj, true, SUBFRAME_RECURSION, + BKE_object_modifier_update_subframe(eval_ctx, scene, brushObj, true, SUBFRAME_RECURSION, BKE_scene_frame_get(scene), eModifierType_DynamicPaint); } @@ -5904,7 +5907,7 @@ static int dynamicPaint_doStep(Scene *scene, SceneLayer *sl, Object *ob, Dynamic return setError(canvas, N_("Not enough free memory")); /* Prepare effects and get number of required steps */ - steps = dynamicPaint_prepareEffectStep(surface, scene, ob, &force, timescale); + steps = dynamicPaint_prepareEffectStep(eval_ctx, surface, scene, ob, &force, timescale); for (s = 0; s < steps; s++) { dynamicPaint_doEffectStep(surface, force, prevPoint, timescale, (float)steps); } @@ -5928,7 +5931,7 @@ static int dynamicPaint_doStep(Scene *scene, SceneLayer *sl, Object *ob, Dynamic /* * Calculate a single frame and included subframes for surface */ -int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Scene *scene, SceneLayer *sl, Object *cObject, int frame) +int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, struct EvaluationContext *eval_ctx, Scene *scene, Object *cObject, int frame) { float timescale = 1.0f; @@ -5937,7 +5940,7 @@ int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Scene *scene, Scen dynamicPaint_applySurfaceDisplace(surface, surface->canvas->dm); /* update bake data */ - dynamicPaint_generateBakeData(surface, sl, cObject); + dynamicPaint_generateBakeData(surface, eval_ctx->scene_layer, cObject); /* don't do substeps for first frame */ if (surface->substeps && (frame != surface->start_frame)) { @@ -5946,10 +5949,10 @@ int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Scene *scene, Scen for (st = 1; st <= surface->substeps; st++) { float subframe = ((float) st) / (surface->substeps + 1); - if (!dynamicPaint_doStep(scene, sl, cObject, surface, timescale, subframe)) + if (!dynamicPaint_doStep(eval_ctx, scene, cObject, surface, timescale, subframe)) return 0; } } - return dynamicPaint_doStep(scene, sl, cObject, surface, timescale, 0.0f); + return dynamicPaint_doStep(eval_ctx, scene, cObject, surface, timescale, 0.0f); } diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index baf91b638b9..df3c652ee19 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -2183,14 +2183,14 @@ static void cage_mapped_verts_callback( } } -float (*BKE_editmesh_vertexCos_get(BMEditMesh *em, Scene *scene, int *r_numVerts))[3] +float (*BKE_editmesh_vertexCos_get(struct EvaluationContext *eval_ctx, BMEditMesh *em, Scene *scene, int *r_numVerts))[3] { DerivedMesh *cage, *final; BLI_bitmap *visit_bitmap; struct CageUserData data; float (*cos_cage)[3]; - cage = editbmesh_get_derived_cage_and_final(scene, em->ob, em, CD_MASK_BAREMESH, &final); + cage = editbmesh_get_derived_cage_and_final(eval_ctx, scene, em->ob, em, CD_MASK_BAREMESH, &final); cos_cage = MEM_callocN(sizeof(*cos_cage) * em->bm->totvert, "bmbvh cos_cage"); /* when initializing cage verts, we only want the first cage coordinate for each vertex, diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 8380588776b..af1d4cc2e7d 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -72,6 +72,7 @@ #include "BKE_scene.h" #include "BKE_smoke.h" +#include "DEG_depsgraph.h" #include "RE_render_ext.h" #include "RE_shader_ext.h" @@ -146,9 +147,10 @@ void free_partdeflect(PartDeflect *pd) MEM_freeN(pd); } -static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd) +static EffectorCache *new_effector_cache(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd) { EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache"); + eff->eval_ctx = eval_ctx; eff->scene = scene; eff->ob = ob; eff->psys = psys; @@ -156,7 +158,7 @@ static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSyste eff->frame = -1; return eff; } -static void add_object_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src, bool for_simulation) +static void add_object_to_effectors(ListBase **effectors, struct EvaluationContext *eval_ctx, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src, bool for_simulation) { EffectorCache *eff = NULL; @@ -174,14 +176,14 @@ static void add_object_to_effectors(ListBase **effectors, Scene *scene, Effector if (*effectors == NULL) *effectors = MEM_callocN(sizeof(ListBase), "effectors list"); - eff = new_effector_cache(scene, ob, NULL, ob->pd); + eff = new_effector_cache(eval_ctx, scene, ob, NULL, ob->pd); /* make sure imat is up to date */ invert_m4_m4(ob->imat, ob->obmat); BLI_addtail(*effectors, eff); } -static void add_particles_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation) +static void add_particles_to_effectors(ListBase **effectors, struct EvaluationContext *eval_ctx, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation) { ParticleSettings *part= psys->part; @@ -195,25 +197,33 @@ static void add_particles_to_effectors(ListBase **effectors, Scene *scene, Effec if (*effectors == NULL) *effectors = MEM_callocN(sizeof(ListBase), "effectors list"); - BLI_addtail(*effectors, new_effector_cache(scene, ob, psys, part->pd)); + BLI_addtail(*effectors, new_effector_cache(eval_ctx, scene, ob, psys, part->pd)); } if (part->pd2 && part->pd2->forcefield && (!for_simulation || weights->weight[part->pd2->forcefield] != 0.0f)) { if (*effectors == NULL) *effectors = MEM_callocN(sizeof(ListBase), "effectors list"); - BLI_addtail(*effectors, new_effector_cache(scene, ob, psys, part->pd2)); + BLI_addtail(*effectors, new_effector_cache(eval_ctx, scene, ob, psys, part->pd2)); } } /* returns ListBase handle with objects taking part in the effecting */ -ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src, +ListBase *pdInitEffectors(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, ParticleSystem *psys_src, EffectorWeights *weights, bool for_simulation) { - SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene); /* Can't get sl from the calling modifiers yet */ + SceneLayer *sl; Base *base; unsigned int layer= ob_src->lay; ListBase *effectors = NULL; + + /* eval_ctx is NULL during deg build */ + if (eval_ctx) { + sl = eval_ctx->scene_layer; + } + else { + sl = BKE_scene_layer_context_active_PLACEHOLDER(scene); + } if (weights->group) { GroupObject *go; @@ -221,13 +231,13 @@ ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src for (go= weights->group->gobject.first; go; go= go->next) { if ( (go->ob->lay & layer) ) { if ( go->ob->pd && go->ob->pd->forcefield ) - add_object_to_effectors(&effectors, scene, weights, go->ob, ob_src, for_simulation); + add_object_to_effectors(&effectors, eval_ctx, scene, weights, go->ob, ob_src, for_simulation); if ( go->ob->particlesystem.first ) { ParticleSystem *psys= go->ob->particlesystem.first; for ( ; psys; psys=psys->next ) - add_particles_to_effectors(&effectors, scene, weights, go->ob, psys, psys_src, for_simulation); + add_particles_to_effectors(&effectors, eval_ctx, scene, weights, go->ob, psys, psys_src, for_simulation); } } } @@ -235,19 +245,19 @@ ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src else { for (base = FIRSTBASE_NEW; base; base = base->next) { if ( base->object->pd && base->object->pd->forcefield ) - add_object_to_effectors(&effectors, scene, weights, base->object, ob_src, for_simulation); + add_object_to_effectors(&effectors, eval_ctx, scene, weights, base->object, ob_src, for_simulation); if ( base->object->particlesystem.first ) { ParticleSystem *psys= base->object->particlesystem.first; for ( ; psys; psys=psys->next ) - add_particles_to_effectors(&effectors, scene, weights, base->object, psys, psys_src, for_simulation); + add_particles_to_effectors(&effectors, eval_ctx, scene, weights, base->object, psys, psys_src, for_simulation); } } } if (for_simulation) - pdPrecalculateEffectors(effectors); + pdPrecalculateEffectors(eval_ctx, effectors); return effectors; } @@ -268,7 +278,7 @@ void pdEndEffectors(ListBase **effectors) } } -static void precalculate_effector(EffectorCache *eff) +static void precalculate_effector(struct EvaluationContext *eval_ctx, EffectorCache *eff) { unsigned int cfra = (unsigned int)(eff->scene->r.cfra >= 0 ? eff->scene->r.cfra : -eff->scene->r.cfra); if (!eff->pd->rng) @@ -280,7 +290,7 @@ static void precalculate_effector(EffectorCache *eff) Curve *cu= eff->ob->data; if (cu->flag & CU_PATH) { if (eff->ob->curve_cache == NULL || eff->ob->curve_cache->path==NULL || eff->ob->curve_cache->path->data==NULL) - BKE_displist_make_curveTypes(eff->scene, eff->ob, 0); + BKE_displist_make_curveTypes(eval_ctx, eff->scene, eff->ob, 0); if (eff->ob->curve_cache->path && eff->ob->curve_cache->path->data) { where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL); @@ -301,19 +311,19 @@ static void precalculate_effector(EffectorCache *eff) if (eff->ob) { float old_vel[3]; - BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra - 1.0f); + BKE_object_where_is_calc_time(eval_ctx, eff->scene, eff->ob, cfra - 1.0f); copy_v3_v3(old_vel, eff->ob->obmat[3]); - BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra); + BKE_object_where_is_calc_time(eval_ctx, eff->scene, eff->ob, cfra); sub_v3_v3v3(eff->velocity, eff->ob->obmat[3], old_vel); } } -void pdPrecalculateEffectors(ListBase *effectors) +void pdPrecalculateEffectors(struct EvaluationContext *eval_ctx, ListBase *effectors) { if (effectors) { EffectorCache *eff = effectors->first; for (; eff; eff=eff->next) - precalculate_effector(eff); + precalculate_effector(eval_ctx, eff); } } @@ -612,6 +622,7 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin } else { ParticleSimulationData sim= {NULL}; + sim.eval_ctx = eff->eval_ctx; sim.scene= eff->scene; sim.ob= eff->ob; sim.psys= eff->psys; diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c index 8247336d915..5599190010d 100644 --- a/source/blender/blenkernel/intern/fluidsim.c +++ b/source/blender/blenkernel/intern/fluidsim.c @@ -65,7 +65,7 @@ // file handling //------------------------------------------------------------------------------- -void initElbeemMesh(struct Scene *scene, struct Object *ob, +void initElbeemMesh(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, int *numVertices, float **vertices, int *numTriangles, int **triangles, int useGlobalCoords, int modifierIndex) @@ -78,7 +78,7 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob, float *verts; int *tris; - dm = mesh_create_derived_index_render(scene, ob, CD_MASK_BAREMESH, modifierIndex); + dm = mesh_create_derived_index_render(eval_ctx, scene, ob, CD_MASK_BAREMESH, modifierIndex); DM_ensure_looptri(dm); diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c index 2c8399adece..1f1f4c9d341 100644 --- a/source/blender/blenkernel/intern/image_gen.c +++ b/source/blender/blenkernel/intern/image_gen.c @@ -132,7 +132,7 @@ static void image_buf_fill_checker_slice(unsigned char *rect, float hsv[3] = {0.0f, 0.9f, 0.9f}; float rgb[3]; - float dark_linear_color, bright_linear_color; + float dark_linear_color = 0.0f, bright_linear_color = 0.0f; if (rect_float != NULL) { dark_linear_color = srgb_to_linearrgb(0.25f); bright_linear_color = srgb_to_linearrgb(0.58f); diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index c6773d98adf..fd984c17356 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -596,7 +596,7 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di /* co: local coord, result local too */ /* returns quaternion for rotation, using cd->no_rot_axis */ /* axis is using another define!!! */ -static bool calc_curve_deform(Scene *scene, Object *par, float co[3], +static bool calc_curve_deform(struct EvaluationContext *eval_ctx, Scene *scene, Object *par, float co[3], const short axis, CurveDeform *cd, float r_quat[4]) { Curve *cu = par->data; @@ -607,7 +607,7 @@ static bool calc_curve_deform(Scene *scene, Object *par, float co[3], /* to be sure, mostly after file load, also cyclic dependencies */ #ifdef CYCLIC_DEPENDENCY_WORKAROUND if (par->curve_cache == NULL) { - BKE_displist_make_curveTypes(scene, par, false); + BKE_displist_make_curveTypes(eval_ctx, scene, par, false); } #endif @@ -700,7 +700,7 @@ static bool calc_curve_deform(Scene *scene, Object *par, float co[3], } void curve_deform_verts( - Scene *scene, Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3], + struct EvaluationContext *eval_ctx, Scene *scene, Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3], int numVerts, const char *vgroup, short defaxis) { Curve *cu; @@ -759,7 +759,7 @@ void curve_deform_verts( if (weight > 0.0f) { mul_m4_v3(cd.curvespace, vertexCos[a]); copy_v3_v3(vec, vertexCos[a]); - calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL); + calc_curve_deform(eval_ctx, scene, cuOb, vec, defaxis, &cd, NULL); interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight); mul_m4_v3(cd.objectspace, vertexCos[a]); } @@ -782,7 +782,7 @@ void curve_deform_verts( if (weight > 0.0f) { /* already in 'cd.curvespace', prev for loop */ copy_v3_v3(vec, vertexCos[a]); - calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL); + calc_curve_deform(eval_ctx, scene, cuOb, vec, defaxis, &cd, NULL); interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight); mul_m4_v3(cd.objectspace, vertexCos[a]); } @@ -793,7 +793,7 @@ void curve_deform_verts( if (cu->flag & CU_DEFORM_BOUNDS_OFF) { for (a = 0; a < numVerts; a++) { mul_m4_v3(cd.curvespace, vertexCos[a]); - calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL); + calc_curve_deform(eval_ctx, scene, cuOb, vertexCos[a], defaxis, &cd, NULL); mul_m4_v3(cd.objectspace, vertexCos[a]); } } @@ -808,7 +808,7 @@ void curve_deform_verts( for (a = 0; a < numVerts; a++) { /* already in 'cd.curvespace', prev for loop */ - calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL); + calc_curve_deform(eval_ctx, scene, cuOb, vertexCos[a], defaxis, &cd, NULL); mul_m4_v3(cd.objectspace, vertexCos[a]); } } @@ -818,7 +818,7 @@ void curve_deform_verts( /* input vec and orco = local coord in armature space */ /* orco is original not-animated or deformed reference point */ /* result written in vec and mat */ -void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, +void curve_deform_vector(struct EvaluationContext *eval_ctx, Scene *scene, Object *cuOb, Object *target, float orco[3], float vec[3], float mat[3][3], int no_rot_axis) { CurveDeform cd; @@ -837,7 +837,7 @@ void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, mul_m4_v3(cd.curvespace, vec); - if (calc_curve_deform(scene, cuOb, vec, target->trackflag, &cd, quat)) { + if (calc_curve_deform(eval_ctx, scene, cuOb, vec, target->trackflag, &cd, quat)) { float qmat[3][3]; quat_to_mat3(qmat, quat); @@ -1027,7 +1027,7 @@ void BKE_lattice_vertexcos_apply(struct Object *ob, float (*vertexCos)[3]) } } -void BKE_lattice_modifiers_calc(Scene *scene, Object *ob) +void BKE_lattice_modifiers_calc(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob) { Lattice *lt = ob->data; VirtualModifierData virtualModifierData; @@ -1054,7 +1054,7 @@ void BKE_lattice_modifiers_calc(Scene *scene, Object *ob) if (mti->type != eModifierTypeType_OnlyDeform) continue; if (!vertexCos) vertexCos = BKE_lattice_vertexcos_get(ob, &numVerts); - mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0); + mti->deformVerts(md, eval_ctx, ob, NULL, vertexCos, numVerts, 0); } /* always displist to make this work like derivedmesh */ @@ -1248,4 +1248,4 @@ void BKE_lattice_batch_cache_free(Lattice *lt) if (lt->batch_cache) { BKE_lattice_batch_cache_free_cb(lt); } -}
\ No newline at end of file +} diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index 3342c198ee1..56b9bd2cc1e 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -90,15 +90,6 @@ SceneLayer *BKE_scene_layer_from_workspace_get(const struct WorkSpace *workspace * This is a placeholder to know which areas of the code need to be addressed for the Workspace changes. * Never use this, you should either use BKE_scene_layer_workspace_active or get SceneLayer explicitly. */ -SceneLayer *BKE_scene_layer_context_active_ex_PLACEHOLDER(const Main *UNUSED(bmain), const Scene *scene) -{ - return BKE_scene_layer_from_scene_get(scene); -} - -/** - * This is a placeholder to know which areas of the code need to be addressed for the Workspace changes. - * Never use this, you should either use BKE_scene_layer_workspace_active or get SceneLayer explicitly. - */ SceneLayer *BKE_scene_layer_context_active_PLACEHOLDER(const Scene *scene) { return BKE_scene_layer_from_scene_get(scene); diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c index a260dffea2f..7310370ca10 100644 --- a/source/blender/blenkernel/intern/library_remap.c +++ b/source/blender/blenkernel/intern/library_remap.c @@ -893,8 +893,13 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b DEG_id_type_tag(bmain, type); #ifdef WITH_PYTHON +#ifdef WITH_PYTHON_SAFETY BPY_id_release(id); #endif + if (id->py_instance) { + BPY_DECREF_RNA_INVALIDATE(id->py_instance); + } +#endif if (do_id_user) { BKE_libblock_relink_ex(bmain, id, NULL, NULL, true); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index e7232322a36..7038fb0ddcf 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1797,3 +1797,13 @@ bool BKE_object_material_edit_image_set(Object *ob, short mat_nr, Image *image) } return false; } + +void BKE_material_eval(struct EvaluationContext *UNUSED(eval_ctx), Material *material) +{ + if (G.debug & G_DEBUG_DEPSGRAPH) { + printf("%s on %s (%p)\n", __func__, material->id.name, material); + } + if ((BLI_listbase_is_empty(&material->gpumaterial) == false)) { + GPU_material_uniform_buffer_tag_dirty(&material->gpumaterial); + } +} diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 8c9690b01df..9be072f1a21 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -387,6 +387,48 @@ void BKE_mesh_ensure_skin_customdata(Mesh *me) } } +bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me) +{ + BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL; + bool changed = false; + if (bm) { + if (!CustomData_has_layer(&bm->pdata, CD_FACEMAP)) { + BM_data_layer_add(bm, &bm->pdata, CD_FACEMAP); + changed = true; + } + } + else { + if (!CustomData_has_layer(&me->pdata, CD_FACEMAP)) { + CustomData_add_layer(&me->pdata, + CD_FACEMAP, + CD_DEFAULT, + NULL, + me->totpoly); + changed = true; + } + } + return changed; +} + +bool BKE_mesh_clear_facemap_customdata(struct Mesh *me) +{ + BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL; + bool changed = false; + if (bm) { + if (CustomData_has_layer(&bm->pdata, CD_FACEMAP)) { + BM_data_layer_free(bm, &bm->pdata, CD_FACEMAP); + changed = true; + } + } + else { + if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) { + CustomData_free_layers(&me->pdata, CD_FACEMAP, me->totpoly); + changed = true; + } + } + return changed; +} + /* this ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or * mloopcol and mcol) have the same relative active/render/clone/mask indices. * @@ -1586,10 +1628,10 @@ void BKE_mesh_to_curve_nurblist(DerivedMesh *dm, ListBase *nurblist, const int e } } -void BKE_mesh_to_curve(Scene *scene, Object *ob) +void BKE_mesh_to_curve(EvaluationContext *eval_ctx, Scene *scene, Object *ob) { /* make new mesh data from the original copy */ - DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_MESH); + DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_MESH); ListBase nurblist = {NULL, NULL}; bool needsFree = false; @@ -2424,7 +2466,7 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals) /* settings: 1 - preview, 2 - render */ Mesh *BKE_mesh_new_from_object( - Main *bmain, Scene *sce, Object *ob, + EvaluationContext *eval_ctx, Main *bmain, Scene *sce, Object *ob, int apply_modifiers, int settings, int calc_tessface, int calc_undeformed) { Mesh *tmpmesh; @@ -2476,7 +2518,7 @@ Mesh *BKE_mesh_new_from_object( copycu->editnurb = tmpcu->editnurb; /* get updated display list, and convert to a mesh */ - BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, false, render); + BKE_displist_make_curveTypes_forRender(eval_ctx, sce, tmpobj, &dispbase, &derivedFinal, false, render); copycu->editfont = NULL; copycu->editnurb = NULL; @@ -2527,13 +2569,7 @@ Mesh *BKE_mesh_new_from_object( if (render) { ListBase disp = {NULL, NULL}; - /* TODO(sergey): This is gonna to work for until EvaluationContext - * only contains for_render flag. As soon as CoW is - * implemented, this is to be rethinked. - */ - EvaluationContext eval_ctx; - DEG_evaluation_context_init(&eval_ctx, DAG_EVAL_RENDER); - BKE_displist_make_mball_forRender(&eval_ctx, sce, ob, &disp); + BKE_displist_make_mball_forRender(eval_ctx, sce, ob, &disp); BKE_mesh_from_metaball(&disp, tmpmesh); BKE_displist_free(&disp); } @@ -2572,9 +2608,9 @@ Mesh *BKE_mesh_new_from_object( /* Write the display mesh into the dummy mesh */ if (render) - dm = mesh_create_derived_render(sce, ob, mask); + dm = mesh_create_derived_render(eval_ctx, sce, ob, mask); else - dm = mesh_create_derived_view(sce, ob, mask); + dm = mesh_create_derived_view(eval_ctx, sce, ob, mask); tmpmesh = BKE_mesh_add(bmain, ((ID *)ob->data)->name + 2); DM_to_mesh(dm, tmpmesh, ob, mask, true); @@ -2691,4 +2727,4 @@ void BKE_mesh_batch_cache_free(Mesh *me) if (me->batch_cache) { BKE_mesh_batch_cache_free_cb(me); } -}
\ No newline at end of file +} diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 2276d56b9c6..b4eb132353c 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -732,8 +732,8 @@ void modifier_path_init(char *path, int path_maxlen, const char *name) /* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */ struct DerivedMesh *modwrap_applyModifier( - ModifierData *md, Object *ob, - struct DerivedMesh *dm, + ModifierData *md, struct EvaluationContext *eval_ctx, + Object *ob, struct DerivedMesh *dm, ModifierApplyFlag flag) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); @@ -742,12 +742,12 @@ struct DerivedMesh *modwrap_applyModifier( if (mti->dependsOnNormals && mti->dependsOnNormals(md)) { DM_ensure_normals(dm); } - return mti->applyModifier(md, ob, dm, flag); + return mti->applyModifier(md, eval_ctx, ob, dm, flag); } struct DerivedMesh *modwrap_applyModifierEM( - ModifierData *md, Object *ob, - struct BMEditMesh *em, + ModifierData *md, struct EvaluationContext *eval_ctx, + Object *ob, struct BMEditMesh *em, DerivedMesh *dm, ModifierApplyFlag flag) { @@ -757,12 +757,12 @@ struct DerivedMesh *modwrap_applyModifierEM( if (mti->dependsOnNormals && mti->dependsOnNormals(md)) { DM_ensure_normals(dm); } - return mti->applyModifierEM(md, ob, em, dm, flag); + return mti->applyModifierEM(md, eval_ctx, ob, em, dm, flag); } void modwrap_deformVerts( - ModifierData *md, Object *ob, - DerivedMesh *dm, + ModifierData *md, struct EvaluationContext *eval_ctx, + Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts, ModifierApplyFlag flag) { @@ -772,11 +772,11 @@ void modwrap_deformVerts( if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) { DM_ensure_normals(dm); } - mti->deformVerts(md, ob, dm, vertexCos, numVerts, flag); + mti->deformVerts(md, eval_ctx, ob, dm, vertexCos, numVerts, flag); } void modwrap_deformVertsEM( - ModifierData *md, Object *ob, + ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { @@ -786,6 +786,6 @@ void modwrap_deformVertsEM( if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) { DM_ensure_normals(dm); } - mti->deformVertsEM(md, ob, em, dm, vertexCos, numVerts); + mti->deformVertsEM(md, eval_ctx, ob, em, dm, vertexCos, numVerts); } /* end modifier callback wrappers */ diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 9679b585e6f..3e4828afb55 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -276,14 +276,14 @@ static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level) return mdisps; } -DerivedMesh *get_multires_dm(Scene *scene, MultiresModifierData *mmd, Object *ob) +DerivedMesh *get_multires_dm(struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *ob) { ModifierData *md = (ModifierData *)mmd; const ModifierTypeInfo *mti = modifierType_getInfo(md->type); - DerivedMesh *tdm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); + DerivedMesh *tdm = mesh_get_derived_deform(eval_ctx, scene, ob, CD_MASK_BAREMESH); DerivedMesh *dm; - dm = mti->applyModifier(md, ob, tdm, MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY); + dm = mti->applyModifier(md, eval_ctx, ob, tdm, MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY); if (dm == tdm) { dm = CDDM_copy(tdm); } @@ -397,10 +397,10 @@ void multires_force_render_update(Object *ob) multires_force_update(ob); } -int multiresModifier_reshapeFromDM(Scene *scene, MultiresModifierData *mmd, +int multiresModifier_reshapeFromDM(struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *ob, DerivedMesh *srcdm) { - DerivedMesh *mrdm = get_multires_dm(scene, mmd, ob); + DerivedMesh *mrdm = get_multires_dm(eval_ctx, scene, mmd, ob); if (mrdm && srcdm && mrdm->getNumVerts(mrdm) == srcdm->getNumVerts(srcdm)) { multires_mvert_to_ss(mrdm, srcdm->getVertArray(srcdm)); @@ -419,13 +419,13 @@ int multiresModifier_reshapeFromDM(Scene *scene, MultiresModifierData *mmd, } /* Returns 1 on success, 0 if the src's totvert doesn't match */ -int multiresModifier_reshape(Scene *scene, MultiresModifierData *mmd, Object *dst, Object *src) +int multiresModifier_reshape(struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *dst, Object *src) { - DerivedMesh *srcdm = mesh_get_derived_final(scene, src, CD_MASK_BAREMESH); - return multiresModifier_reshapeFromDM(scene, mmd, dst, srcdm); + DerivedMesh *srcdm = mesh_get_derived_final(eval_ctx, scene, src, CD_MASK_BAREMESH); + return multiresModifier_reshapeFromDM(eval_ctx, scene, mmd, dst, srcdm); } -int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mmd, +int multiresModifier_reshapeFromDeformMod(struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *ob, ModifierData *md) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); @@ -437,12 +437,12 @@ int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mm return 0; /* Create DerivedMesh for deformation modifier */ - dm = get_multires_dm(scene, mmd, ob); + dm = get_multires_dm(eval_ctx, scene, mmd, ob); numVerts = dm->getNumVerts(dm); deformedVerts = MEM_mallocN(sizeof(float[3]) * numVerts, "multiresReshape_deformVerts"); dm->getVertCos(dm, deformedVerts); - mti->deformVerts(md, ob, dm, deformedVerts, numVerts, 0); + mti->deformVerts(md, eval_ctx, ob, dm, deformedVerts, numVerts, 0); ndm = CDDM_copy(dm); CDDM_apply_vert_coords(ndm, deformedVerts); @@ -451,7 +451,7 @@ int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mm dm->release(dm); /* Reshaping */ - result = multiresModifier_reshapeFromDM(scene, mmd, ob, ndm); + result = multiresModifier_reshapeFromDM(eval_ctx, scene, mmd, ob, ndm); /* Cleanup */ ndm->release(ndm); @@ -2174,7 +2174,7 @@ static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst) } } -static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3]) +static void multires_apply_smat(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float smat[3][3]) { DerivedMesh *dm = NULL, *cddm = NULL, *subdm = NULL; CCGElem **gridData, **subGridData; @@ -2199,10 +2199,10 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3]) high_mmd.lvl = high_mmd.totlvl; /* unscaled multires with applied displacement */ - subdm = get_multires_dm(scene, &high_mmd, ob); + subdm = get_multires_dm(eval_ctx, scene, &high_mmd, ob); /* prepare scaled CDDM to create ccgDN */ - cddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); + cddm = mesh_get_derived_deform(eval_ctx, scene, ob, CD_MASK_BAREMESH); totvert = cddm->getNumVerts(cddm); vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "multiresScale vertCos"); @@ -2276,17 +2276,17 @@ int multires_mdisp_corners(MDisps *s) return 0; } -void multiresModifier_scale_disp(Scene *scene, Object *ob) +void multiresModifier_scale_disp(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob) { float smat[3][3]; /* object's scale matrix */ BKE_object_scale_to_mat3(ob, smat); - multires_apply_smat(scene, ob, smat); + multires_apply_smat(eval_ctx, scene, ob, smat); } -void multiresModifier_prepare_join(Scene *scene, Object *ob, Object *to_ob) +void multiresModifier_prepare_join(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *to_ob) { float smat[3][3], tmat[3][3], mat[3][3]; multires_sync_levels(scene, to_ob, ob); @@ -2297,7 +2297,7 @@ void multiresModifier_prepare_join(Scene *scene, Object *ob, Object *to_ob) BKE_object_scale_to_mat3(ob, smat); mul_m3_m3m3(mat, smat, tmat); - multires_apply_smat(scene, ob, mat); + multires_apply_smat(eval_ctx, scene, ob, mat); } /* update multires data after topology changing */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 5f99421ccb3..d7c60f67c05 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -365,6 +365,8 @@ void BKE_object_free_derived_caches(Object *ob) } if (ob->mesh_evaluated != NULL) { + /* Restore initial pointer. */ + ob->data = ob->mesh_evaluated->id.newid; /* Evaluated mesh points to edit mesh, but does not own it. */ ob->mesh_evaluated->edit_btmesh = NULL; BKE_mesh_free(ob->mesh_evaluated); @@ -1710,13 +1712,16 @@ static bool ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4]) Curve *cu = par->data; float vec[4], dir[3], quat[4], radius, ctime; + /* TODO: Make sure this doesn't crash. */ +#if 0 /* only happens on reload file, but violates depsgraph still... fix! */ if (par->curve_cache == NULL) { if (scene == NULL) { return false; } - BKE_displist_make_curveTypes(scene, par, 0); + BKE_displist_make_curveTypes(eval_ctx, scene, par, 0); } +#endif if (par->curve_cache->path == NULL) { return false; @@ -2097,7 +2102,7 @@ static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat } /* note, scene is the active scene while actual_scene is the scene the object resides in */ -void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime, +void BKE_object_where_is_calc_time_ex(EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime, RigidBodyWorld *rbw, float r_originmat[3][3]) { if (ob == NULL) return; @@ -2133,7 +2138,7 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime, if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) { bConstraintOb *cob; cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT); - BKE_constraints_solve(&ob->constraints, cob, ctime); + BKE_constraints_solve(eval_ctx, &ob->constraints, cob, ctime); BKE_constraints_clear_evalob(cob); } @@ -2142,9 +2147,9 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime, else ob->transflag &= ~OB_NEG_SCALE; } -void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime) +void BKE_object_where_is_calc_time(EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime) { - BKE_object_where_is_calc_time_ex(scene, ob, ctime, NULL, NULL); + BKE_object_where_is_calc_time_ex(eval_ctx, scene, ob, ctime, NULL, NULL); } /* get object transformation matrix without recalculating dependencies and @@ -2169,17 +2174,17 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4]) } } -void BKE_object_where_is_calc_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3]) +void BKE_object_where_is_calc_ex(EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3]) { - BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), rbw, r_originmat); + BKE_object_where_is_calc_time_ex(eval_ctx, scene, ob, BKE_scene_frame_get(scene), rbw, r_originmat); } -void BKE_object_where_is_calc(Scene *scene, Object *ob) +void BKE_object_where_is_calc(EvaluationContext *eval_ctx, Scene *scene, Object *ob) { - BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), NULL, NULL); + BKE_object_where_is_calc_time_ex(eval_ctx, scene, ob, BKE_scene_frame_get(scene), NULL, NULL); } /* for calculation of the inverse parent transform, only used for editor */ -void BKE_object_workob_calc_parent(Scene *scene, Object *ob, Object *workob) +void BKE_object_workob_calc_parent(EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *workob) { BKE_object_workob_clear(workob); @@ -2201,7 +2206,7 @@ void BKE_object_workob_calc_parent(Scene *scene, Object *ob, Object *workob) BLI_strncpy(workob->parsubstr, ob->parsubstr, sizeof(workob->parsubstr)); - BKE_object_where_is_calc(scene, workob); + BKE_object_where_is_calc(eval_ctx, scene, workob); } /* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */ @@ -2680,7 +2685,7 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx, copy_m4_m4(ob->obmat, ob->proxy_from->obmat); } else - BKE_object_where_is_calc_ex(scene, rbw, ob, NULL); + BKE_object_where_is_calc_ex(eval_ctx, scene, rbw, ob, NULL); } if (ob->recalc & OB_RECALC_DATA) { @@ -3626,7 +3631,7 @@ static void object_cacheIgnoreClear(Object *ob, int state) /* Note: this function should eventually be replaced by depsgraph functionality. * Avoid calling this in new code unless there is a very good reason for it! */ -bool BKE_object_modifier_update_subframe(Scene *scene, Object *ob, bool update_mesh, +bool BKE_object_modifier_update_subframe(EvaluationContext *eval_ctx, Scene *scene, Object *ob, bool update_mesh, int parent_recursion, float frame, int type) { @@ -3651,8 +3656,8 @@ bool BKE_object_modifier_update_subframe(Scene *scene, Object *ob, bool update_m if (parent_recursion) { int recursion = parent_recursion - 1; bool no_update = false; - if (ob->parent) no_update |= BKE_object_modifier_update_subframe(scene, ob->parent, 0, recursion, frame, type); - if (ob->track) no_update |= BKE_object_modifier_update_subframe(scene, ob->track, 0, recursion, frame, type); + if (ob->parent) no_update |= BKE_object_modifier_update_subframe(eval_ctx, scene, ob->parent, 0, recursion, frame, type); + if (ob->track) no_update |= BKE_object_modifier_update_subframe(eval_ctx, scene, ob->track, 0, recursion, frame, type); /* skip subframe if object is parented * to vertex of a dynamic paint canvas */ @@ -3669,7 +3674,7 @@ bool BKE_object_modifier_update_subframe(Scene *scene, Object *ob, bool update_m cti->get_constraint_targets(con, &targets); for (ct = targets.first; ct; ct = ct->next) { if (ct->tar) - BKE_object_modifier_update_subframe(scene, ct->tar, 0, recursion, frame, type); + BKE_object_modifier_update_subframe(eval_ctx, scene, ct->tar, 0, recursion, frame, type); } /* free temp targets */ if (cti->flush_constraint_targets) @@ -3689,7 +3694,7 @@ bool BKE_object_modifier_update_subframe(Scene *scene, Object *ob, bool update_m object_cacheIgnoreClear(ob, 0); } else - BKE_object_where_is_calc_time(scene, ob, frame); + BKE_object_where_is_calc_time(eval_ctx, scene, ob, frame); /* for curve following objects, parented curve has to be updated too */ if (ob->type == OB_CURVE) { @@ -3700,7 +3705,7 @@ bool BKE_object_modifier_update_subframe(Scene *scene, Object *ob, bool update_m if (ob->type == OB_ARMATURE) { bArmature *arm = ob->data; BKE_animsys_evaluate_animdata(scene, &arm->id, arm->adt, frame, ADT_RECALC_ANIM); - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(eval_ctx, scene, ob); } return false; diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 1f10ed25249..66cacd67a85 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -341,7 +341,7 @@ static void make_duplis_group(const DupliContext *ctx) } } -const DupliGenerator gen_dupli_group = { +static const DupliGenerator gen_dupli_group = { OB_DUPLIGROUP, /* type */ make_duplis_group /* make_duplis */ }; @@ -397,7 +397,7 @@ static void make_duplis_frames(const DupliContext *ctx) * However, this has always been the way that this worked (i.e. pre 2.5), so I guess that it'll be fine! */ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ - BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra); + BKE_object_where_is_calc_time(ctx->eval_ctx, scene, ob, (float)scene->r.cfra); make_dupli(ctx, ob, ob->obmat, scene->r.cfra, false, false); } @@ -411,7 +411,7 @@ static void make_duplis_frames(const DupliContext *ctx) scene->r.cfra = cfrao; BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ - BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra); + BKE_object_where_is_calc_time(ctx->eval_ctx, scene, ob, (float)scene->r.cfra); /* but, to make sure unkeyed object transforms are still sane, * let's copy object's original data back over @@ -419,7 +419,7 @@ static void make_duplis_frames(const DupliContext *ctx) *ob = copyob; } -const DupliGenerator gen_dupli_frames = { +static const DupliGenerator gen_dupli_frames = { OB_DUPLIFRAMES, /* type */ make_duplis_frames /* make_duplis */ }; @@ -546,13 +546,13 @@ static void make_duplis_verts(const DupliContext *ctx) CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO : CD_MASK_BAREMESH); if (ctx->eval_ctx->mode == DAG_EVAL_RENDER) { - vdd.dm = mesh_create_derived_render(scene, parent, dm_mask); + vdd.dm = mesh_create_derived_render(ctx->eval_ctx, scene, parent, dm_mask); } else if (em) { - vdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask); + vdd.dm = editbmesh_get_derived_cage(ctx->eval_ctx, scene, parent, em, dm_mask); } else { - vdd.dm = mesh_get_derived_final(scene, parent, dm_mask); + vdd.dm = mesh_get_derived_final(ctx->eval_ctx, scene, parent, dm_mask); } vdd.edit_btmesh = me->edit_btmesh; @@ -569,7 +569,7 @@ static void make_duplis_verts(const DupliContext *ctx) vdd.dm->release(vdd.dm); } -const DupliGenerator gen_dupli_verts = { +static const DupliGenerator gen_dupli_verts = { OB_DUPLIVERTS, /* type */ make_duplis_verts /* make_duplis */ }; @@ -682,7 +682,7 @@ static void make_duplis_font(const DupliContext *ctx) MEM_freeN(chartransdata); } -const DupliGenerator gen_dupli_verts_font = { +static const DupliGenerator gen_dupli_verts_font = { OB_DUPLIVERTS, /* type */ make_duplis_font /* make_duplis */ }; @@ -814,13 +814,13 @@ static void make_duplis_faces(const DupliContext *ctx) CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO | CD_MASK_MLOOPUV : CD_MASK_BAREMESH); if (ctx->eval_ctx->mode == DAG_EVAL_RENDER) { - fdd.dm = mesh_create_derived_render(scene, parent, dm_mask); + fdd.dm = mesh_create_derived_render(ctx->eval_ctx, scene, parent, dm_mask); } else if (em) { - fdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask); + fdd.dm = editbmesh_get_derived_cage(ctx->eval_ctx, scene, parent, em, dm_mask); } else { - fdd.dm = mesh_get_derived_final(scene, parent, dm_mask); + fdd.dm = mesh_get_derived_final(ctx->eval_ctx, scene, parent, dm_mask); } if (use_texcoords) { @@ -845,7 +845,7 @@ static void make_duplis_faces(const DupliContext *ctx) fdd.dm->release(fdd.dm); } -const DupliGenerator gen_dupli_faces = { +static const DupliGenerator gen_dupli_faces = { OB_DUPLIFACES, /* type */ make_duplis_faces /* make_duplis */ }; @@ -898,6 +898,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem if ((psys->renderdata || 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; sim.ob = par; sim.psys = psys; @@ -1079,7 +1080,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem } else { /* to give ipos in object correct offset */ - BKE_object_where_is_calc_time(scene, ob, ctime - pa_time); + BKE_object_where_is_calc_time(ctx->eval_ctx, scene, ob, ctime - pa_time); copy_v3_v3(vec, obmat[3]); obmat[3][0] = obmat[3][1] = obmat[3][2] = 0.0f; @@ -1166,7 +1167,7 @@ static void make_duplis_particles(const DupliContext *ctx) } } -const DupliGenerator gen_dupli_particles = { +static const DupliGenerator gen_dupli_particles = { OB_DUPLIPARTS, /* type */ make_duplis_particles /* make_duplis */ }; @@ -1271,7 +1272,7 @@ int count_duplilist(Object *ob) return 1; } -DupliApplyData *duplilist_apply(Object *ob, Scene *scene, ListBase *duplilist) +DupliApplyData *duplilist_apply(EvaluationContext *eval_ctx, Object *ob, Scene *scene, ListBase *duplilist) { DupliApplyData *apply_data = NULL; int num_objects = BLI_listbase_count(duplilist); @@ -1287,7 +1288,7 @@ DupliApplyData *duplilist_apply(Object *ob, Scene *scene, ListBase *duplilist) for (dob = duplilist->first, i = 0; dob; dob = dob->next, ++i) { /* make sure derivedmesh is calculated once, before drawing */ if (scene && !(dob->ob->transflag & OB_DUPLICALCDERIVED) && dob->ob->type == OB_MESH) { - mesh_get_derived_final(scene, dob->ob, scene->customdata_mask); + mesh_get_derived_final(eval_ctx, scene, dob->ob, scene->customdata_mask); dob->ob->transflag |= OB_DUPLICALCDERIVED; } } diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 50502115edc..0bbfbb8a4e7 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -113,7 +113,7 @@ void BKE_object_eval_parent(EvaluationContext *UNUSED(eval_ctx), } } -void BKE_object_eval_constraints(EvaluationContext *UNUSED(eval_ctx), +void BKE_object_eval_constraints(EvaluationContext *eval_ctx, Scene *scene, Object *ob) { @@ -132,7 +132,7 @@ void BKE_object_eval_constraints(EvaluationContext *UNUSED(eval_ctx), * */ cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT); - BKE_constraints_solve(&ob->constraints, cob, ctime); + BKE_constraints_solve(eval_ctx, &ob->constraints, cob, ctime); BKE_constraints_clear_evalob(cob); } @@ -184,10 +184,10 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx, } #endif if (em) { - makeDerivedMesh(scene, ob, em, data_mask, false); /* was CD_MASK_BAREMESH */ + makeDerivedMesh(eval_ctx, scene, ob, em, data_mask, false); /* was CD_MASK_BAREMESH */ } else { - makeDerivedMesh(scene, ob, NULL, data_mask, false); + makeDerivedMesh(eval_ctx, scene, ob, NULL, data_mask, false); } break; } @@ -199,7 +199,7 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx, } } else { - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(eval_ctx, scene, ob); } break; @@ -210,11 +210,11 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx, case OB_CURVE: case OB_SURF: case OB_FONT: - BKE_displist_make_curveTypes(scene, ob, 0); + BKE_displist_make_curveTypes(eval_ctx, scene, ob, 0); break; case OB_LATTICE: - BKE_lattice_modifiers_calc(scene, ob); + BKE_lattice_modifiers_calc(eval_ctx, scene, ob); break; case OB_EMPTY: @@ -267,7 +267,7 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx, ob->transflag |= OB_DUPLIPARTS; } - particle_system_update(scene, ob, psys, (eval_ctx->mode == DAG_EVAL_RENDER)); + particle_system_update(eval_ctx, scene, ob, psys, (eval_ctx->mode == DAG_EVAL_RENDER)); psys = psys->next; } else if (psys->flag & PSYS_DELETE) { @@ -285,7 +285,7 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx, * the derivedmesh must be created before init_render_mesh, * since object_duplilist does dupliparticles before that */ CustomDataMask data_mask = CD_MASK_BAREMESH | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL; - dm = mesh_create_derived_render(scene, ob, data_mask); + dm = mesh_create_derived_render(eval_ctx, scene, ob, data_mask); dm->release(dm); for (psys = ob->particlesystem.first; psys; psys = psys->next) @@ -361,7 +361,7 @@ void BKE_object_eval_uber_data(EvaluationContext *eval_ctx, /* Copy materials so render engines can access them. */ new_mesh->mat = MEM_dupallocN(mesh->mat); new_mesh->totcol = mesh->totcol; - DM_to_mesh(dm, new_mesh, ob, ob->lastDataMask, true); + DM_to_mesh(dm, new_mesh, ob, CD_MASK_MESH, true); new_mesh->edit_btmesh = mesh->edit_btmesh; /* Store result mesh as derived_mesh of object. This way we have * explicit way to query final object evaluated data and know for sure @@ -377,6 +377,11 @@ void BKE_object_eval_uber_data(EvaluationContext *eval_ctx, /* NOTE: Watch out, some tools might need it! * So keep around for now.. */ + /* Store original ID as a pointer in evaluated ID. + * This way we can restore original object data when we are freeing + * evaluated mesh. + */ + new_mesh->id.newid = &mesh->id; } #if 0 if (ob->derivedFinal != NULL) { diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index c798a1587ee..eebe514c7ca 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -823,7 +823,7 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob) /** * \param need_mask So the DerivedMesh thats returned has mask data */ -void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, +void BKE_sculpt_update_mesh_elements(EvaluationContext *eval_ctx, Scene *scene, Sculpt *sd, Object *ob, bool need_pmap, bool need_mask) { DerivedMesh *dm; @@ -860,7 +860,7 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, ss->kb = (mmd == NULL) ? BKE_keyblock_from_object(ob) : NULL; - dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH); if (mmd) { ss->multires = mmd; @@ -893,7 +893,7 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, ss->orig_cos = (ss->kb) ? BKE_keyblock_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL); - BKE_crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos); + BKE_crazyspace_build_sculpt(eval_ctx, scene, ob, &ss->deform_imats, &ss->deform_cos); BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos); for (a = 0; a < me->totvert; ++a) { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 9a3da64e7d8..baa4214123e 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1856,7 +1856,7 @@ void precalc_guides(ParticleSimulationData *sim, ListBase *effectors) } } -int do_guides(ParticleSettings *part, ListBase *effectors, ParticleKey *state, int index, float time) +int do_guides(EvaluationContext *eval_ctx, ParticleSettings *part, ListBase *effectors, ParticleKey *state, int index, float time) { CurveMapping *clumpcurve = (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) ? part->clumpcurve : NULL; CurveMapping *roughcurve = (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) ? part->roughcurve : NULL; @@ -1919,7 +1919,7 @@ int do_guides(ParticleSettings *part, ListBase *effectors, ParticleKey *state, i /* curve taper */ if (cu->taperobj) - mul_v3_fl(vec_to_point, BKE_displist_calc_taper(eff->scene, cu->taperobj, (int)(data->strength * guidetime * 100.0f), 100)); + mul_v3_fl(vec_to_point, BKE_displist_calc_taper(eval_ctx, eff->scene, cu->taperobj, (int)(data->strength * guidetime * 100.0f), 100)); else { /* curve size*/ if (cu->flag & CU_PATH_RADIUS) { @@ -2720,7 +2720,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re if (sim->psys->effectors && (psys->part->flag & PART_CHILD_EFFECT) == 0) { for (k = 0, ca = cache[p]; k <= segments; k++, ca++) /* ca is safe to cast, since only co and vel are used */ - do_guides(sim->psys->part, sim->psys->effectors, (ParticleKey *)ca, p, (float)k / (float)segments); + do_guides(sim->eval_ctx, sim->psys->part, sim->psys->effectors, (ParticleKey *)ca, p, (float)k / (float)segments); } /* lattices have to be calculated separately to avoid mixups between effector calculations */ @@ -2768,7 +2768,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re if (vg_length) MEM_freeN(vg_length); } -void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cfra, const bool use_render_params) +void psys_cache_edit_paths(EvaluationContext *eval_ctx, Scene *scene, Object *ob, PTCacheEdit *edit, float cfra, const bool use_render_params) { ParticleCacheKey *ca, **cache = edit->pathcache; ParticleEditSettings *pset = &scene->toolsettings->particle; @@ -2959,6 +2959,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf if (psys) { ParticleSimulationData sim = {0}; + sim.eval_ctx = eval_ctx; sim.scene = scene; sim.ob = ob; sim.psys = psys; @@ -3790,7 +3791,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * mul_mat3_m4_v3(hairmat, state->vel); if (sim->psys->effectors && (part->flag & PART_CHILD_GUIDE) == 0) { - do_guides(sim->psys->part, sim->psys->effectors, state, p, state->time); + do_guides(sim->eval_ctx, sim->psys->part, sim->psys->effectors, state, p, state->time); /* TODO: proper velocity handling */ } @@ -4317,9 +4318,10 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3] madd_v3_v3fl(center, yvec, bb->offset[1]); } -void psys_apply_hair_lattice(Scene *scene, Object *ob, ParticleSystem *psys) +void psys_apply_hair_lattice(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys) { ParticleSimulationData sim = {0}; + sim.eval_ctx = eval_ctx; sim.scene = scene; sim.ob = ob; sim.psys = psys; diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c index bfcda89a635..d2ad05c20b7 100644 --- a/source/blender/blenkernel/intern/particle_child.c +++ b/source/blender/blenkernel/intern/particle_child.c @@ -702,7 +702,7 @@ void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, if (part->flag & PART_CHILD_EFFECT) /* state is safe to cast, since only co and vel are used */ - guided = do_guides(sim->psys->part, sim->psys->effectors, (ParticleKey *)state, cpa->parent, t); + guided = do_guides(sim->eval_ctx, sim->psys->part, sim->psys->effectors, (ParticleKey *)state, cpa->parent, t); if (guided == 0) { float orco_offset[3]; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index a6ed50fd0e9..044f52832e6 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -980,14 +980,14 @@ void psys_get_birth_coords(ParticleSimulationData *sim, ParticleData *pa, Partic } /* recursively evaluate emitter parent anim at cfra */ -static void evaluate_emitter_anim(Scene *scene, Object *ob, float cfra) +static void evaluate_emitter_anim(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float cfra) { if (ob->parent) - evaluate_emitter_anim(scene, ob->parent, cfra); + evaluate_emitter_anim(eval_ctx, scene, ob->parent, cfra); /* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, cfra, ADT_RECALC_ANIM); - BKE_object_where_is_calc_time(scene, ob, cfra); + BKE_object_where_is_calc_time(eval_ctx, scene, ob, cfra); } /* sets particle to the emitter surface with initial velocity & rotation */ @@ -1001,7 +1001,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, /* get precise emitter matrix if particle is born */ if (part->type != PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) { - evaluate_emitter_anim(sim->scene, sim->ob, pa->time); + evaluate_emitter_anim(sim->eval_ctx, sim->scene, sim->ob, pa->time); psys->flag |= PSYS_OB_ANIM_RESTORE; } @@ -1133,7 +1133,8 @@ static void set_keyed_keys(ParticleSimulationData *sim) int totpart = psys->totpart, k, totkeys = psys->totkeyed; int keyed_flag = 0; - ksim.scene= sim->scene; + ksim.eval_ctx = sim->eval_ctx; + ksim.scene = sim->scene; /* no proper targets so let's clear and bail out */ if (psys->totkeyed==0) { @@ -1294,7 +1295,7 @@ void psys_update_particle_tree(ParticleSystem *psys, float cfra) static void psys_update_effectors(ParticleSimulationData *sim) { pdEndEffectors(&sim->psys->effectors); - sim->psys->effectors = pdInitEffectors(sim->scene, sim->ob, sim->psys, + sim->psys->effectors = pdInitEffectors(sim->eval_ctx, sim->scene, sim->ob, sim->psys, sim->psys->part->effector_weights, true); precalc_guides(sim, sim->psys->effectors); } @@ -2115,7 +2116,7 @@ static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, floa tkey.time=pa->state.time; if (part->type != PART_HAIR) { - if (do_guides(sim->psys->part, sim->psys->effectors, &tkey, p, time)) { + if (do_guides(sim->eval_ctx, sim->psys->part, sim->psys->effectors, &tkey, p, time)) { copy_v3_v3(pa->state.co,tkey.co); /* guides don't produce valid velocity */ sub_v3_v3v3(pa->state.vel, tkey.co, pa->prev_state.co); @@ -3043,10 +3044,12 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int /* calculate maximum segment length */ max_length = 0.0f; LOOP_PARTICLES { - for (k=1, key=pa->hair+1; k<pa->totkey; k++,key++) { - float length = len_v3v3(key->co, (key-1)->co); - if (max_length < length) - max_length = length; + if (!(pa->flag & PARS_UNEXIST)) { + for (k=1, key=pa->hair+1; k<pa->totkey; k++,key++) { + float length = len_v3v3(key->co, (key-1)->co); + if (max_length < length) + max_length = length; + } } } @@ -3058,76 +3061,78 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int /* make vgroup for pin roots etc.. */ hair_index = 1; LOOP_PARTICLES { - float root_mat[4][4]; - float bending_stiffness; - bool use_hair; - - pa->hair_index = hair_index; - use_hair = psys_hair_use_simulation(pa, max_length); - - psys_mat_hair_to_object(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat); - mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat); - normalize_m4(root_mat); - - bending_stiffness = CLAMPIS(1.0f - part->bending_random * psys_frand(psys, p + 666), 0.0f, 1.0f); - - for (k=0, key=pa->hair; k<pa->totkey; k++,key++) { - ClothHairData *hair; - float *co, *co_next; - - co = key->co; - co_next = (key+1)->co; - - /* create fake root before actual root to resist bending */ - if (k==0) { - hair = &psys->clmd->hairdata[pa->hair_index - 1]; + if (!(pa->flag & PARS_UNEXIST)) { + float root_mat[4][4]; + float bending_stiffness; + bool use_hair; + + pa->hair_index = hair_index; + use_hair = psys_hair_use_simulation(pa, max_length); + + psys_mat_hair_to_object(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat); + mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat); + normalize_m4(root_mat); + + bending_stiffness = CLAMPIS(1.0f - part->bending_random * psys_frand(psys, p + 666), 0.0f, 1.0f); + + for (k=0, key=pa->hair; k<pa->totkey; k++,key++) { + ClothHairData *hair; + float *co, *co_next; + + co = key->co; + co_next = (key+1)->co; + + /* create fake root before actual root to resist bending */ + if (k==0) { + hair = &psys->clmd->hairdata[pa->hair_index - 1]; + copy_v3_v3(hair->loc, root_mat[3]); + copy_m3_m4(hair->rot, root_mat); + + hair->radius = hair_radius; + hair->bending_stiffness = bending_stiffness; + + add_v3_v3v3(mvert->co, co, co); + sub_v3_v3(mvert->co, co_next); + mul_m4_v3(hairmat, mvert->co); + + medge->v1 = pa->hair_index - 1; + medge->v2 = pa->hair_index; + + dvert = hair_set_pinning(dvert, 1.0f); + + mvert++; + medge++; + } + + /* store root transform in cloth data */ + hair = &psys->clmd->hairdata[pa->hair_index + k]; copy_v3_v3(hair->loc, root_mat[3]); copy_m3_m4(hair->rot, root_mat); - + hair->radius = hair_radius; hair->bending_stiffness = bending_stiffness; - - add_v3_v3v3(mvert->co, co, co); - sub_v3_v3(mvert->co, co_next); + + copy_v3_v3(mvert->co, co); mul_m4_v3(hairmat, mvert->co); - - medge->v1 = pa->hair_index - 1; - medge->v2 = pa->hair_index; - - dvert = hair_set_pinning(dvert, 1.0f); - + + if (k) { + medge->v1 = pa->hair_index + k - 1; + medge->v2 = pa->hair_index + k; + } + + /* roots and disabled hairs should be 1.0, the rest can be anything from 0.0 to 1.0 */ + if (use_hair) + dvert = hair_set_pinning(dvert, key->weight); + else + dvert = hair_set_pinning(dvert, 1.0f); + mvert++; - medge++; + if (k) + medge++; } - - /* store root transform in cloth data */ - hair = &psys->clmd->hairdata[pa->hair_index + k]; - copy_v3_v3(hair->loc, root_mat[3]); - copy_m3_m4(hair->rot, root_mat); - - hair->radius = hair_radius; - hair->bending_stiffness = bending_stiffness; - - copy_v3_v3(mvert->co, co); - mul_m4_v3(hairmat, mvert->co); - - if (k) { - medge->v1 = pa->hair_index + k - 1; - medge->v2 = pa->hair_index + k; - } - - /* roots and disabled hairs should be 1.0, the rest can be anything from 0.0 to 1.0 */ - if (use_hair) - dvert = hair_set_pinning(dvert, key->weight); - else - dvert = hair_set_pinning(dvert, 1.0f); - - mvert++; - if (k) - medge++; + + hair_index += pa->totkey + 1; } - - hair_index += pa->totkey + 1; } } @@ -3153,9 +3158,11 @@ static void do_hair_dynamics(ParticleSimulationData *sim) totpoint = 0; totedge = 0; LOOP_PARTICLES { - /* "out" dm contains all hairs */ - totedge += pa->totkey; - totpoint += pa->totkey + 1; /* +1 for virtual root point */ + if (!(pa->flag & PARS_UNEXIST)) { + /* "out" dm contains all hairs */ + totedge += pa->totkey; + totpoint += pa->totkey + 1; /* +1 for virtual root point */ + } } realloc_roots = false; /* whether hair root info array has to be reallocated */ @@ -3191,7 +3198,7 @@ static void do_hair_dynamics(ParticleSimulationData *sim) psys->hair_out_dm = CDDM_copy(psys->hair_in_dm); psys->hair_out_dm->getVertCos(psys->hair_out_dm, deformedVerts); - clothModifier_do(psys->clmd, sim->scene, sim->ob, psys->hair_in_dm, deformedVerts); + clothModifier_do(psys->clmd, sim->eval_ctx, sim->scene, sim->ob, psys->hair_in_dm, deformedVerts); CDDM_apply_vert_coords(psys->hair_out_dm, deformedVerts); @@ -4151,7 +4158,7 @@ static int hair_needs_recalc(ParticleSystem *psys) /* main particle update call, checks that things are ok on the large scale and * then advances in to actual particle calculations depending on particle type */ -void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys, const bool use_render_params) +void particle_system_update(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys, const bool use_render_params) { ParticleSimulationData sim= {0}; ParticleSettings *part = psys->part; @@ -4165,10 +4172,11 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys, cons cfra= BKE_scene_frame_get(scene); - sim.scene= scene; - sim.ob= ob; - sim.psys= psys; - sim.psmd= psys_get_modifier(ob, psys); + sim.eval_ctx = eval_ctx; + sim.scene = scene; + sim.ob = ob; + sim.psys = psys; + sim.psmd = psys_get_modifier(ob, psys); /* system was already updated from modifier stack */ if (sim.psmd->flag & eParticleSystemFlag_psys_updated) { @@ -4311,7 +4319,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys, cons /* make sure emitter is left at correct time (particle emission can change this) */ if (psys->flag & PSYS_OB_ANIM_RESTORE) { - evaluate_emitter_anim(scene, ob, cfra); + evaluate_emitter_anim(eval_ctx, scene, ob, cfra); psys->flag &= ~PSYS_OB_ANIM_RESTORE; } @@ -4353,13 +4361,30 @@ void BKE_particlesystem_id_loop(ParticleSystem *psys, ParticleSystemIDFunc func, /* **** Depsgraph evaluation **** */ -void BKE_particle_system_eval(struct EvaluationContext *UNUSED(eval_ctx), - Scene *scene, - Object *ob, - ParticleSystem *psys) +void BKE_particle_system_settings_eval(struct EvaluationContext *UNUSED(eval_ctx), + ParticleSystem *psys) +{ + if (G.debug & G_DEBUG_DEPSGRAPH) { + printf("%s on %s (%p)\n", __func__, psys->name, psys); + } + psys->recalc |= psys->part->recalc; +} + +void BKE_particle_system_settings_recalc_clear(struct EvaluationContext *UNUSED(eval_ctx), + ParticleSettings *particle_settings) +{ + if (G.debug & G_DEBUG_DEPSGRAPH) { + printf("%s on %s (%p)\n", __func__, particle_settings->id.name, particle_settings); + } + particle_settings->recalc = 0; +} + +void BKE_particle_system_eval_init(struct EvaluationContext *UNUSED(eval_ctx), + Scene *scene, + Object *ob) { if (G.debug & G_DEBUG_DEPSGRAPH) { - printf("%s on %s:%s\n", __func__, ob->id.name, psys->name); + printf("%s on %s (%p)\n", __func__, ob->id.name, ob); } BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH); } diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index a2b5ac4359d..ee78bc4d678 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -1226,7 +1226,7 @@ static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw) rigidbody_update_ob_array(rbw); } -static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo) +static void rigidbody_update_sim_ob(struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo) { float loc[3]; float rot[4]; @@ -1274,7 +1274,7 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o ListBase *effectors; /* get effectors present in the group specified by effector_weights */ - effectors = pdInitEffectors(scene, ob, NULL, effector_weights, true); + effectors = pdInitEffectors(eval_ctx, scene, ob, NULL, effector_weights, true); if (effectors) { float eff_force[3] = {0.0f, 0.0f, 0.0f}; float eff_loc[3], eff_vel[3]; @@ -1315,7 +1315,7 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o * * \param rebuild Rebuild entire simulation */ -static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool rebuild) +static void rigidbody_update_simulation(struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, bool rebuild) { GroupObject *go; @@ -1352,7 +1352,7 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool /* validate that we've got valid object set up here... */ RigidBodyOb *rbo = ob->rigidbody_object; /* update transformation matrix of the object so we don't get a frame of lag for simple animations */ - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(eval_ctx, scene, ob); if (rbo == NULL) { /* Since this object is included in the sim group but doesn't have @@ -1386,7 +1386,7 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool } /* update simulation object... */ - rigidbody_update_sim_ob(scene, rbw, ob, rbo); + rigidbody_update_sim_ob(eval_ctx, scene, rbw, ob, rbo); } } @@ -1400,7 +1400,7 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool /* validate that we've got valid object set up here... */ RigidBodyCon *rbc = ob->rigidbody_constraint; /* update transformation matrix of the object so we don't get a frame of lag for simple animations */ - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(eval_ctx, scene, ob); if (rbc == NULL) { /* Since this object is included in the group but doesn't have @@ -1559,7 +1559,7 @@ void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) /* Rebuild rigid body world */ /* NOTE: this needs to be called before frame update to work correctly */ -void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) +void BKE_rigidbody_rebuild_world(struct EvaluationContext *eval_ctx, Scene *scene, float ctime) { RigidBodyWorld *rbw = scene->rigidbody_world; PointCache *cache; @@ -1578,7 +1578,7 @@ void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) if (ctime == startframe + 1 && rbw->ltime == startframe) { if (cache->flag & PTCACHE_OUTDATED) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); - rigidbody_update_simulation(scene, rbw, true); + rigidbody_update_simulation(eval_ctx, scene, rbw, true); BKE_ptcache_validate(cache, (int)ctime); cache->last_exact = 0; cache->flag &= ~PTCACHE_REDO_NEEDED; @@ -1587,7 +1587,7 @@ void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) } /* Run RigidBody simulation for the specified physics world */ -void BKE_rigidbody_do_simulation(Scene *scene, float ctime) +void BKE_rigidbody_do_simulation(struct EvaluationContext *eval_ctx, Scene *scene, float ctime) { float timestep; RigidBodyWorld *rbw = scene->rigidbody_world; @@ -1631,7 +1631,7 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime) } /* update and validate simulation */ - rigidbody_update_simulation(scene, rbw, false); + rigidbody_update_simulation(eval_ctx, scene, rbw, false); /* calculate how much time elapsed since last step in seconds */ timestep = 1.0f / (float)FPS * (ctime - rbw->ltime) * rbw->time_scale; @@ -1675,8 +1675,8 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {} bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) { return false; } void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {} -void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) {} -void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {} +void BKE_rigidbody_rebuild_world(struct EvaluationContext *eval_ctx, Scene *scene, float ctime) {} +void BKE_rigidbody_do_simulation(struct EvaluationContext *eval_ctx, Scene *scene, float ctime) {} #ifdef __GNUC__ # pragma GCC diagnostic pop @@ -1687,7 +1687,7 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {} /* -------------------- */ /* Depsgraph evaluation */ -void BKE_rigidbody_rebuild_sim(struct EvaluationContext *UNUSED(eval_ctx), +void BKE_rigidbody_rebuild_sim(struct EvaluationContext *eval_ctx, Scene *scene) { float ctime = BKE_scene_frame_get(scene); @@ -1698,11 +1698,11 @@ void BKE_rigidbody_rebuild_sim(struct EvaluationContext *UNUSED(eval_ctx), /* rebuild sim data (i.e. after resetting to start of timeline) */ if (BKE_scene_check_rigidbody_active(scene)) { - BKE_rigidbody_rebuild_world(scene, ctime); + BKE_rigidbody_rebuild_world(eval_ctx, scene, ctime); } } -void BKE_rigidbody_eval_simulation(struct EvaluationContext *UNUSED(eval_ctx), +void BKE_rigidbody_eval_simulation(struct EvaluationContext *eval_ctx, Scene *scene) { float ctime = BKE_scene_frame_get(scene); @@ -1713,7 +1713,7 @@ void BKE_rigidbody_eval_simulation(struct EvaluationContext *UNUSED(eval_ctx), /* evaluate rigidbody sim */ if (BKE_scene_check_rigidbody_active(scene)) { - BKE_rigidbody_do_simulation(scene, ctime); + BKE_rigidbody_do_simulation(eval_ctx, scene, ctime); } } diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index f3a93a0a42c..a07abe166f0 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -292,6 +292,32 @@ void BKE_spacedata_id_unref(struct ScrArea *sa, struct SpaceLink *sl, struct ID } } +/** + * Avoid bad-level calls to #WM_manipulatormap_tag_refresh. + */ +static void (*region_refresh_tag_manipulatormap_callback)(struct wmManipulatorMap *) = NULL; + +void BKE_region_callback_refresh_tag_manipulatormap_set(void (*callback)(struct wmManipulatorMap *)) +{ + region_refresh_tag_manipulatormap_callback = callback; +} + +void BKE_screen_manipulator_tag_refresh(struct bScreen *sc) +{ + if (region_refresh_tag_manipulatormap_callback == NULL) { + return; + } + + ScrArea *sa; + ARegion *ar; + for (sa = sc->areabase.first; sa; sa = sa->next) { + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->manipulator_map != NULL) { + region_refresh_tag_manipulatormap_callback(ar->manipulator_map); + } + } + } +} /** * Avoid bad-level calls to #WM_manipulatormap_delete. @@ -353,7 +379,10 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar) } } - region_free_manipulatormap_callback(ar->manipulator_map); + if (ar->manipulator_map != NULL) { + region_free_manipulatormap_callback(ar->manipulator_map); + } + BLI_freelistN(&ar->ui_lists); BLI_freelistN(&ar->ui_previews); BLI_freelistN(&ar->panels_category); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 6ddce874449..0c384f8b8c8 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -3306,7 +3306,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene); ibuf = sequencer_view3d_cb( /* set for OpenGL render (NULL when scrubbing) */ - scene, BKE_scene_layer_from_scene_get(scene), camera, width, height, IB_rect, + context->eval_ctx, scene, BKE_scene_layer_from_scene_get(scene), camera, width, height, IB_rect, context->scene->r.seq_prev_type, (context->scene->r.seq_flag & R_SEQ_SOLID_TEX) != 0, use_gpencil, use_background, scene->r.alphamode, diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 667f8d1e8c7..664305ac715 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -83,6 +83,8 @@ #include "BKE_smoke.h" #include "BKE_texture.h" +#include "DEG_depsgraph.h" + #include "RE_shader_ext.h" #include "GPU_glew.h" @@ -126,7 +128,7 @@ void smoke_initWaveletBlenderRNA(struct WTURBULENCE *UNUSED(wt), float *UNUSED(s void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity), int *UNUSED(border_colli), float *UNUSED(burning_rate), float *UNUSED(flame_smoke), float *UNUSED(flame_smoke_color), float *UNUSED(flame_vorticity), float *UNUSED(flame_ignition_temp), float *UNUSED(flame_max_temp)) {} -struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), SceneLayer *UNUSED(sl), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; } +struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), struct EvaluationContext *UNUSED(eval_ctx), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; } float smoke_get_velocity_at(struct Object *UNUSED(ob), float UNUSED(position[3]), float UNUSED(velocity[3])) { return 0.0f; } #endif /* WITH_SMOKE */ @@ -2071,7 +2073,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value } } -static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt) +static void update_flowsfluids(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt) { Object **flowobjs = NULL; EmissionMap *emaps = NULL; @@ -2178,7 +2180,7 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd else { /* MOD_SMOKE_FLOW_SOURCE_MESH */ /* update flow object frame */ BLI_mutex_lock(&object_update_lock); - BKE_object_modifier_update_subframe(scene, collob, true, 5, BKE_scene_frame_get(scene), eModifierType_Smoke); + BKE_object_modifier_update_subframe(eval_ctx, scene, collob, true, 5, BKE_scene_frame_get(scene), eModifierType_Smoke); BLI_mutex_unlock(&object_update_lock); /* apply flow */ @@ -2487,12 +2489,12 @@ static void update_effectors_task_cb(void *userdata, const int x) } } -static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, float UNUSED(dt)) +static void update_effectors(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeDomainSettings *sds, float UNUSED(dt)) { ListBase *effectors; /* make sure smoke flow influence is 0.0f */ sds->effector_weights->weight[PFIELD_SMOKEFLOW] = 0.0f; - effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights, true); + effectors = pdInitEffectors(eval_ctx, scene, ob, NULL, sds->effector_weights, true); if (effectors) { // precalculate wind forces @@ -2516,7 +2518,7 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, pdEndEffectors(&effectors); } -static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh *domain_dm, float fps) +static void step(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh *domain_dm, float fps) { SmokeDomainSettings *sds = smd->domain; /* stability values copied from wturbulence.cpp */ @@ -2586,11 +2588,11 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh * for (substep = 0; substep < totalSubsteps; substep++) { // calc animated obstacle velocities - update_flowsfluids(scene, ob, sds, dtSubdiv); + update_flowsfluids(eval_ctx, scene, ob, sds, dtSubdiv); update_obstacles(scene, ob, sds, dtSubdiv, substep, totalSubsteps); if (sds->total_cells > 1) { - update_effectors(scene, ob, sds, dtSubdiv); // DG TODO? problem --> uses forces instead of velocity, need to check how they need to be changed with variable dt + update_effectors(eval_ctx, scene, ob, sds, dtSubdiv); // DG TODO? problem --> uses forces instead of velocity, need to check how they need to be changed with variable dt smoke_step(sds->fluid, gravity, dtSubdiv); } } @@ -2683,7 +2685,7 @@ static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob) return result; } -static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, SceneLayer *sl, Object *ob, DerivedMesh *dm) +static void smokeModifier_process(SmokeModifierData *smd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm) { if ((smd->type & MOD_SMOKE_TYPE_FLOW)) { @@ -2806,11 +2808,11 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, SceneLay } - step(scene, ob, smd, dm, scene->r.frs_sec / scene->r.frs_sec_base); + step(eval_ctx, scene, ob, smd, dm, scene->r.frs_sec / scene->r.frs_sec_base); } // create shadows before writing cache so they get stored - smoke_calc_transparency(sds, sl); + smoke_calc_transparency(sds, eval_ctx->scene_layer); if (sds->wt && sds->total_cells > 1) { smoke_turbulence_step(sds->wt, sds->fluid); @@ -2827,13 +2829,13 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, SceneLay } } -struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, SceneLayer *sl, Object *ob, DerivedMesh *dm) +struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm) { /* lock so preview render does not read smoke data while it gets modified */ if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) BLI_rw_mutex_lock(smd->domain->fluid_mutex, THREAD_LOCK_WRITE); - smokeModifier_process(smd, scene, sl, ob, dm); + smokeModifier_process(smd, eval_ctx, scene, ob, dm); if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) BLI_rw_mutex_unlock(smd->domain->fluid_mutex); diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 0b8c11f6dc8..4d8270568ba 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -81,6 +81,8 @@ variables on the UI for now #include "BKE_mesh.h" #include "BKE_scene.h" +#include "DEG_depsgraph.h" + #include "PIL_time.h" /* callbacks for errors and interrupts and some goo */ @@ -1544,12 +1546,12 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, } -static void scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow) +static void scan_for_ext_spring_forces(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float timenow) { SoftBody *sb = ob->soft; ListBase *do_effector = NULL; - do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights, true); + do_effector = pdInitEffectors(eval_ctx, scene, ob, NULL, sb->effector_weights, true); _scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector); pdEndEffectors(&do_effector); } @@ -1561,7 +1563,7 @@ static void *exec_scan_for_ext_spring_forces(void *data) return NULL; } -static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow, int totsprings, int *UNUSED(ptr_to_break_func(void))) +static void sb_sfesf_threads_run(struct EvaluationContext *eval_ctx, Scene *scene, struct Object *ob, float timenow, int totsprings, int *UNUSED(ptr_to_break_func(void))) { ListBase *do_effector = NULL; ListBase threads; @@ -1569,7 +1571,7 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow, int i, totthread, left, dec; int lowsprings =100; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */ - do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights, true); + do_effector= pdInitEffectors(eval_ctx, scene, ob, NULL, ob->soft->effector_weights, true); /* figure the number of threads while preventing pretty pointless threading overhead */ totthread= BKE_scene_num_threads(scene); @@ -2233,7 +2235,7 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t MEM_freeN(sb_threads); } -static void softbody_calc_forcesEx(Scene *scene, SceneLayer *sl, Object *ob, float forcetime, float timenow) +static void softbody_calc_forcesEx(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float forcetime, float timenow) { /* rule we never alter free variables :bp->vec bp->pos in here ! * this will ruin adaptive stepsize AKA heun! (BM) @@ -2249,7 +2251,7 @@ static void softbody_calc_forcesEx(Scene *scene, SceneLayer *sl, Object *ob, flo /* gravity = sb->grav * sb_grav_force_scale(ob); */ /* UNUSED */ /* check conditions for various options */ - do_deflector= query_external_colliders(sl, sb->collision_group); + do_deflector= query_external_colliders(eval_ctx->scene_layer, sb->collision_group); /* do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF)); */ /* UNUSED */ do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL); do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES)); @@ -2258,10 +2260,10 @@ static void softbody_calc_forcesEx(Scene *scene, SceneLayer *sl, Object *ob, flo /* bproot= sb->bpoint; */ /* need this for proper spring addressing */ /* UNUSED */ if (do_springcollision || do_aero) - sb_sfesf_threads_run(scene, ob, timenow, sb->totspring, NULL); + sb_sfesf_threads_run(eval_ctx, scene, ob, timenow, sb->totspring, NULL); /* after spring scan because it uses Effoctors too */ - do_effector= pdInitEffectors(scene, ob, NULL, sb->effector_weights, true); + do_effector= pdInitEffectors(eval_ctx, scene, ob, NULL, sb->effector_weights, true); if (do_deflector) { float defforce[3]; @@ -2278,11 +2280,11 @@ static void softbody_calc_forcesEx(Scene *scene, SceneLayer *sl, Object *ob, flo } -static void softbody_calc_forces(Scene *scene, SceneLayer *sl, Object *ob, float forcetime, float timenow) +static void softbody_calc_forces(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float forcetime, float timenow) { /* redirection to the new threaded Version */ if (!(G.debug_value & 0x10)) { // 16 - softbody_calc_forcesEx(scene, sl, ob, forcetime, timenow); + softbody_calc_forcesEx(eval_ctx, scene, ob, forcetime, timenow); return; } else { @@ -2313,7 +2315,7 @@ static void softbody_calc_forces(Scene *scene, SceneLayer *sl, Object *ob, float } /* check conditions for various options */ - do_deflector= query_external_colliders(sl, sb->collision_group); + do_deflector= query_external_colliders(eval_ctx->scene_layer, sb->collision_group); do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF)); do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL); do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES)); @@ -2321,9 +2323,9 @@ static void softbody_calc_forces(Scene *scene, SceneLayer *sl, Object *ob, float iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */ /* bproot= sb->bpoint; */ /* need this for proper spring addressing */ /* UNUSED */ - if (do_springcollision || do_aero) scan_for_ext_spring_forces(scene, ob, timenow); + if (do_springcollision || do_aero) scan_for_ext_spring_forces(eval_ctx, scene, ob, timenow); /* after spring scan because it uses Effoctors too */ - do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights, true); + do_effector= pdInitEffectors(eval_ctx, scene, ob, NULL, ob->soft->effector_weights, true); if (do_deflector) { float defforce[3]; @@ -3510,7 +3512,7 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int } } -static void softbody_step(Scene *scene, SceneLayer *sl, Object *ob, SoftBody *sb, float dtime) +static void softbody_step(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SoftBody *sb, float dtime) { /* the simulator */ float forcetime; @@ -3524,11 +3526,11 @@ static void softbody_step(Scene *scene, SceneLayer *sl, Object *ob, SoftBody *sb */ if (dtime < 0 || dtime > 10.5f) return; - ccd_update_deflector_hash(sl, sb->collision_group, ob, sb->scratch->colliderhash); + ccd_update_deflector_hash(eval_ctx->scene_layer, sb->collision_group, ob, sb->scratch->colliderhash); if (sb->scratch->needstobuildcollider) { - if (query_external_colliders(sl, sb->collision_group)) { - ccd_build_deflector_hash(sl, sb->collision_group, ob, sb->scratch->colliderhash); + if (query_external_colliders(eval_ctx->scene_layer, sb->collision_group)) { + ccd_build_deflector_hash(eval_ctx->scene_layer, sb->collision_group, ob, sb->scratch->colliderhash); } sb->scratch->needstobuildcollider=0; } @@ -3558,12 +3560,12 @@ static void softbody_step(Scene *scene, SceneLayer *sl, Object *ob, SoftBody *sb sb->scratch->flag &= ~SBF_DOFUZZY; /* do predictive euler step */ - softbody_calc_forces(scene, sl, ob, forcetime, timedone/dtime); + softbody_calc_forces(eval_ctx, scene, ob, forcetime, timedone/dtime); softbody_apply_forces(ob, forcetime, 1, NULL, mid_flags); /* crop new slope values to do averaged slope step */ - softbody_calc_forces(scene, sl, ob, forcetime, timedone/dtime); + softbody_calc_forces(eval_ctx, scene, ob, forcetime, timedone/dtime); softbody_apply_forces(ob, forcetime, 2, &err, mid_flags); softbody_apply_goalsnap(ob); @@ -3644,7 +3646,7 @@ static void softbody_step(Scene *scene, SceneLayer *sl, Object *ob, SoftBody *sb } /* simulates one step. framenr is in frames */ -void sbObjectStep(Scene *scene, SceneLayer *sl, Object *ob, float cfra, float (*vertexCos)[3], int numVerts) +void sbObjectStep(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], int numVerts) { SoftBody *sb= ob->soft; PointCache *cache; @@ -3759,7 +3761,7 @@ void sbObjectStep(Scene *scene, SceneLayer *sl, Object *ob, float cfra, float (* dtime = framedelta*timescale; /* do simulation */ - softbody_step(scene, sl, ob, sb, dtime); + softbody_step(eval_ctx, scene, ob, sb, dtime); softbody_to_object(ob, vertexCos, numVerts, 0); diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index c0a373395dc..8606da0743b 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -372,6 +372,12 @@ static size_t unit_as_string(char *str, int len_max, double value, int prec, con value_conv = value / unit->scalar; + /* Adjust precision to expected number of significant digits. + * Note that here, we shall not have to worry about very big/small numbers, units are expected to replace + * 'scientific notation' in those cases. */ + prec -= integer_digits_d(value_conv); + CLAMP(prec, 0, 6); + /* Convert to a string */ len = BLI_snprintf_rlen(str, len_max, "%.*f", prec, value_conv); @@ -442,12 +448,15 @@ size_t bUnit_AsString(char *str, int len_max, double value, int prec, int system size_t i; i = unit_as_string(str, len_max, value_a, prec, usys, unit_a, '\0'); + prec -= integer_digits_d(value_a / unit_b->scalar) - integer_digits_d(value_b / unit_b->scalar); + prec = max_ii(prec, 0); + /* is there enough space for at least 1 char of the next unit? */ if (i + 2 < len_max) { str[i++] = ' '; /* use low precision since this is a smaller unit */ - i += unit_as_string(str + i, len_max - i, value_b, prec ? 1 : 0, usys, unit_b, '\0'); + i += unit_as_string(str + i, len_max - i, value_b, prec, usys, unit_b, '\0'); } return i; } diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 363c36e644d..2adbdc83a36 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -175,3 +175,14 @@ void BKE_world_make_local(Main *bmain, World *wrld, const bool lib_local) { BKE_id_make_local_generic(bmain, &wrld->id, true, lib_local); } + +void BKE_world_eval(struct EvaluationContext *UNUSED(eval_ctx), World *world) +{ + if (G.debug & G_DEBUG_DEPSGRAPH) { + printf("%s on %s (%p)\n", __func__, world->id.name, world); + } + if (!BLI_listbase_is_empty(&world->gpumaterial)) { + world->update_flag = 1; + GPU_material_uniform_buffer_tag_dirty(&world->gpumaterial); + } +} diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h index 74f24c808ff..3ffca818c0d 100644 --- a/source/blender/blenlib/BLI_array.h +++ b/source/blender/blenlib/BLI_array.h @@ -135,11 +135,12 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static, #define BLI_array_append_ret(arr) \ (BLI_array_reserve(arr, 1), &arr[(_##arr##_count++)]) -#define BLI_array_free(arr) \ +#define BLI_array_free(arr) { \ if (arr && (char *)arr != _##arr##_static) { \ BLI_array_fake_user(arr); \ MEM_freeN(arr); \ - } (void)0 + } \ +} ((void)0) #define BLI_array_pop(arr) ( \ (arr && _##arr##_count) ? \ diff --git a/source/blender/blenlib/BLI_compiler_compat.h b/source/blender/blenlib/BLI_compiler_compat.h index 01fc9d70207..0726e3bb343 100644 --- a/source/blender/blenlib/BLI_compiler_compat.h +++ b/source/blender/blenlib/BLI_compiler_compat.h @@ -48,12 +48,7 @@ extern "C++" { #if defined(_MSC_VER) # define BLI_INLINE static __forceinline #else -# if (defined(__APPLE__) && defined(__ppc__)) -/* static inline __attribute__ here breaks osx ppc gcc42 build */ -# define BLI_INLINE static __attribute__((always_inline)) __attribute__((__unused__)) -# else -# define BLI_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__)) -# endif +# define BLI_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__)) #endif #endif /* __BLI_COMPILER_COMPAT_H__ */ diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index 0126e30d900..c44b666faea 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -138,6 +138,9 @@ MINLINE int signum_i(float a); MINLINE float power_of_2(float f); +MINLINE int integer_digits_f(const float f); +MINLINE int integer_digits_d(const double d); + /* these don't really fit anywhere but were being copied about a lot */ MINLINE int is_power_of_2_i(int n); MINLINE int power_of_2_max_i(int n); diff --git a/source/blender/blenlib/BLI_math_inline.h b/source/blender/blenlib/BLI_math_inline.h index 840cf24f8cf..383abda5b2f 100644 --- a/source/blender/blenlib/BLI_math_inline.h +++ b/source/blender/blenlib/BLI_math_inline.h @@ -44,12 +44,7 @@ extern "C" { # define MALWAYS_INLINE MINLINE # else # define MINLINE static inline -# if (defined(__APPLE__) && defined(__ppc__)) - /* static inline __attribute__ here breaks osx ppc gcc42 build */ -# define MALWAYS_INLINE static __attribute__((always_inline)) __attribute__((unused)) -# else -# define MALWAYS_INLINE static inline __attribute__((always_inline)) __attribute__((unused)) -# endif +# define MALWAYS_INLINE static inline __attribute__((always_inline)) __attribute__((unused)) # endif #else # define MINLINE diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 90aff1fcbbc..f098449ebd0 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -85,29 +85,47 @@ void mul_m4_m4_pre(float R[4][4], const float A[4][4]); void mul_m4_m4_post(float R[4][4], const float B[4][4]); /* mul_m3_series */ -void _va_mul_m3_series_3(float R[3][3], float M1[3][3], float M2[3][3]) ATTR_NONNULL(); -void _va_mul_m3_series_4(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3]) ATTR_NONNULL(); -void _va_mul_m3_series_5(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3]) ATTR_NONNULL(); -void _va_mul_m3_series_6(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3], - float M5[3][3]) ATTR_NONNULL(); -void _va_mul_m3_series_7(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3], - float M5[3][3], float M6[3][3]) ATTR_NONNULL(); -void _va_mul_m3_series_8(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3], - float M5[3][3], float M6[3][3], float M7[3][3]) ATTR_NONNULL(); -void _va_mul_m3_series_9(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3], - float M5[3][3], float M6[3][3], float M7[3][3], float M8[3][3]) ATTR_NONNULL(); +void _va_mul_m3_series_3( + float R[3][3], const float M1[3][3], const float M2[3][3]) ATTR_NONNULL(); +void _va_mul_m3_series_4( + float R[3][3], const float M1[3][3], const float M2[3][3], const float M3[3][3]) ATTR_NONNULL(); +void _va_mul_m3_series_5( + float R[3][3], const float M1[3][3], const float M2[3][3], const float M3[3][3], + const float M4[3][3]) ATTR_NONNULL(); +void _va_mul_m3_series_6( + float R[3][3], const float M1[3][3], const float M2[3][3], const float M3[3][3], + const float M4[3][3], const float M5[3][3]) ATTR_NONNULL(); +void _va_mul_m3_series_7( + float R[3][3], const float M1[3][3], const float M2[3][3], const float M3[3][3], + const float M4[3][3], const float M5[3][3], const float M6[3][3]) ATTR_NONNULL(); +void _va_mul_m3_series_8( + float R[3][3], const float M1[3][3], const float M2[3][3], const float M3[3][3], + const float M4[3][3], const float M5[3][3], const float M6[3][3], const float M7[3][3]) ATTR_NONNULL(); +void _va_mul_m3_series_9( + float R[3][3], const float M1[3][3], const float M2[3][3], const float M3[3][3], + const float M4[3][3], const float M5[3][3], const float M6[3][3], const float M7[3][3], + const float M8[3][3]) ATTR_NONNULL(); /* mul_m4_series */ -void _va_mul_m4_series_3(float R[4][4], float M1[4][4], float M2[4][4]) ATTR_NONNULL(); -void _va_mul_m4_series_4(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4]) ATTR_NONNULL(); -void _va_mul_m4_series_5(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4], float M4[4][4]) ATTR_NONNULL(); -void _va_mul_m4_series_6(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4], float M4[4][4], - float M5[4][4]) ATTR_NONNULL(); -void _va_mul_m4_series_7(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4], float M4[4][4], - float M5[4][4], float M6[4][4]) ATTR_NONNULL(); -void _va_mul_m4_series_8(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4], float M4[4][4], - float M5[4][4], float M6[4][4], float M7[4][4]) ATTR_NONNULL(); -void _va_mul_m4_series_9(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4], float M4[4][4], - float M5[4][4], float M6[4][4], float M7[4][4], float M8[4][4]) ATTR_NONNULL(); +void _va_mul_m4_series_3( + float R[4][4], const float M1[4][4], const float M2[4][4]) ATTR_NONNULL(); +void _va_mul_m4_series_4( + float R[4][4], const float M1[4][4], const float M2[4][4], const float M3[4][4]) ATTR_NONNULL(); +void _va_mul_m4_series_5( + float R[4][4], const float M1[4][4], const float M2[4][4], const float M3[4][4], + const float M4[4][4]) ATTR_NONNULL(); +void _va_mul_m4_series_6( + float R[4][4], const float M1[4][4], const float M2[4][4], const float M3[4][4], + const float M4[4][4], const float M5[4][4]) ATTR_NONNULL(); +void _va_mul_m4_series_7( + float R[4][4], const float M1[4][4], const float M2[4][4], const float M3[4][4], + const float M4[4][4], const float M5[4][4], const float M6[4][4]) ATTR_NONNULL(); +void _va_mul_m4_series_8( + float R[4][4], const float M1[4][4], const float M2[4][4], const float M3[4][4], + const float M4[4][4], const float M5[4][4], const float M6[4][4], const float M7[4][4]) ATTR_NONNULL(); +void _va_mul_m4_series_9( + float R[4][4], const float M1[4][4], const float M2[4][4], const float M3[4][4], + const float M4[4][4], const float M5[4][4], const float M6[4][4], const float M7[4][4], + const float M8[4][4]) ATTR_NONNULL(); #define mul_m3_series(...) VA_NARGS_CALL_OVERLOAD(_va_mul_m3_series_, __VA_ARGS__) #define mul_m4_series(...) VA_NARGS_CALL_OVERLOAD(_va_mul_m4_series_, __VA_ARGS__) diff --git a/source/blender/blenlib/BLI_memiter.h b/source/blender/blenlib/BLI_memiter.h new file mode 100644 index 00000000000..36877d8f4ba --- /dev/null +++ b/source/blender/blenlib/BLI_memiter.h @@ -0,0 +1,72 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BLI_MEMITER_H__ +#define __BLI_MEMITER_H__ + +/** \file BLI_memiter.h + * \ingroup bli + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "BLI_compiler_attrs.h" +#include "BLI_compiler_compat.h" + +/* 512kb, good default for small elems. */ +#define BLI_MEMITER_DEFAULT_SIZE (1 << 19) + +struct BLI_memiter; +struct BLI_memiter_chunk; + +typedef struct BLI_memiter BLI_memiter; + +/* warning, ATTR_MALLOC flag on BLI_memiter_alloc causes crash, see: D2756 */ +BLI_memiter *BLI_memiter_create(unsigned int chunk_size) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +void *BLI_memiter_alloc(BLI_memiter *mi, unsigned int size) ATTR_RETURNS_NONNULL ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +void BLI_memiter_alloc_from(BLI_memiter *mi, uint elem_size, const void *data_from) ATTR_NONNULL(1, 3); +void *BLI_memiter_calloc(BLI_memiter *mi, unsigned int size) ATTR_RETURNS_NONNULL ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +void BLI_memiter_destroy(BLI_memiter *mi) ATTR_NONNULL(1); +void BLI_memiter_clear(BLI_memiter *mi) ATTR_NONNULL(1); +unsigned int BLI_memiter_count(const BLI_memiter *mi) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); + +/* utils */ +void *BLI_memiter_elem_first(BLI_memiter *mi); +void *BLI_memiter_elem_first_size(BLI_memiter *mi, unsigned int *r_size); + +/* private structure */ +typedef struct BLI_memiter_handle { + struct BLI_memiter_elem *elem; + uint elem_left; +} BLI_memiter_handle; + +void BLI_memiter_iter_init(BLI_memiter *mi, BLI_memiter_handle *iter) ATTR_NONNULL(); +bool BLI_memiter_iter_done(const BLI_memiter_handle *iter) ATTR_NONNULL(); +void *BLI_memiter_iter_step(BLI_memiter_handle *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +void *BLI_memiter_iter_step_size(BLI_memiter_handle *iter, uint *r_size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); + +#ifdef __cplusplus +} +#endif + +#endif /* __BLI_MEMITER_H__ */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index dc81ce000ea..1d865f99239 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -50,6 +50,7 @@ set(SRC intern/BLI_kdtree.c intern/BLI_linklist.c intern/BLI_memarena.c + intern/BLI_memiter.c intern/BLI_mempool.c intern/DLRB_tree.c intern/array_store.c @@ -179,6 +180,7 @@ set(SRC BLI_math_statistics.h BLI_math_vector.h BLI_memarena.h + BLI_memiter.h BLI_memory_utils.h BLI_mempool.h BLI_noise.h diff --git a/source/blender/blenlib/intern/BLI_memiter.c b/source/blender/blenlib/intern/BLI_memiter.c new file mode 100644 index 00000000000..c86c26f578a --- /dev/null +++ b/source/blender/blenlib/intern/BLI_memiter.c @@ -0,0 +1,357 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenlib/intern/BLI_memiter.c + * \ingroup bli + * + * Simple, fast memory allocator for allocating many small elements of different sizes + * in fixed size memory chunks, + * although allocations bigger than the chunk size are supported. + * They will reduce the efficiency of this data-structure. + * Elements are pointer aligned. + * + * Supports: + * + * - Allocation of mixed sizes. + * - Iterating over allocations in-order. + * - Clearing for re-use. + * + * Unsupported: + * + * - Freeing individual elements. + * + * \note We could inline iteration stepping, + * but tests show this doesn't give noticeable speedup. + */ + +#include <string.h> +#include <stdlib.h> + +#include "BLI_utildefines.h" + +#include "BLI_memiter.h" /* own include */ + +#include "MEM_guardedalloc.h" + +#include "BLI_strict_flags.h" /* keep last */ + +typedef uintptr_t data_t; +typedef intptr_t offset_t; + +/* Write the chunk terminator on adding each element. + * typically we rely on the 'count' to avoid iterating past the end. */ +// #define USE_TERMINATE_PARANOID + +/* Currently totalloc isnt used. */ + // #define USE_TOTALLOC + +/* pad must be power of two */ +#define PADUP(num, pad) (((num) + ((pad) - 1)) & ~((pad) - 1)) + +typedef struct BLI_memiter_elem { + offset_t size; + data_t data[0]; +} BLI_memiter_elem; + +typedef struct BLI_memiter_chunk { + struct BLI_memiter_chunk *next; + /** + * internal format is: + * ``[next_pointer, size:data, size:data, ..., negative_offset]`` + * + * Where negative offset rewinds to the start. + */ + data_t data[0]; +} BLI_memiter_chunk; + +typedef struct BLI_memiter { + /* A pointer to 'head' is needed so we can iterate in the order allocated. */ + struct BLI_memiter_chunk *head, *tail; + data_t *data_curr; + data_t *data_last; + /* Used unless a large element is requested. + * (which should be very rare!). */ + uint chunk_size_in_bytes_min; + uint count; +#ifdef USE_TOTALLOC + uint totalloc; +#endif +} BLI_memiter; + + +BLI_INLINE uint data_offset_from_size(uint size) +{ + return (PADUP(size, (uint)sizeof(data_t))) / (uint)sizeof(data_t); +} + +static void memiter_set_rewind_offset(BLI_memiter *mi) +{ + BLI_memiter_elem *elem = (BLI_memiter_elem *)mi->data_curr; + elem->size = (offset_t)(((data_t *)mi->tail) - mi->data_curr); + BLI_assert(elem->size < 0); +} + +static void memiter_init(BLI_memiter *mi) +{ + mi->head = NULL; + mi->tail = NULL; + mi->data_curr = NULL; + mi->data_last = NULL; + mi->count = 0; +#ifdef USE_TOTALLOC + mi->totalloc = 0; +#endif +} + +/* -------------------------------------------------------------------- */ + +/** \name Public API's + * \{ */ + +/** + * \param chunk_size_min: Should be a power of two and + * significantly larger than the average element size used. + * + * While allocations of any size are supported, they won't be efficient + * (effectively becoming a single-linked list). + * + * Its intended that many elements can be stored per chunk. + */ +BLI_memiter *BLI_memiter_create(uint chunk_size_min) +{ + BLI_memiter *mi = MEM_mallocN(sizeof(BLI_memiter), "BLI_memiter"); + memiter_init(mi); + + /* Small values are used for tests to check for correctness, + * but otherwise not that useful. */ + const uint slop_space = (sizeof(BLI_memiter_chunk) + MEM_SIZE_OVERHEAD); + if (chunk_size_min >= 1024) { + /* As long as the input is a power of 2, this will give efficient sizes. */ + chunk_size_min -= slop_space; + } + + mi->chunk_size_in_bytes_min = (offset_t)chunk_size_min; + return mi; +} + +void *BLI_memiter_alloc(BLI_memiter *mi, uint elem_size) +{ + const uint data_offset = data_offset_from_size(elem_size); + data_t *data_curr_next = mi->data_curr + (1 + data_offset); + + if (UNLIKELY(mi->data_curr == NULL) || (data_curr_next > mi->data_last)) { + +#ifndef USE_TERMINATE_PARANOID + if (mi->data_curr != NULL) { + memiter_set_rewind_offset(mi); + } +#endif + + uint chunk_size_in_bytes = mi->chunk_size_in_bytes_min; + if (UNLIKELY(chunk_size_in_bytes < elem_size + (uint)sizeof(data_t[2]))) { + chunk_size_in_bytes = elem_size + (uint)sizeof(data_t[2]); + } + uint chunk_size = data_offset_from_size(chunk_size_in_bytes); + BLI_memiter_chunk *chunk = MEM_mallocN( + sizeof(BLI_memiter_chunk) + + (chunk_size * sizeof(data_t)), + "BLI_memiter_chunk"); + + if (mi->head == NULL) { + BLI_assert(mi->tail == NULL); + mi->head = chunk; + } + else { + mi->tail->next = chunk; + } + mi->tail = chunk; + chunk->next = NULL; + + mi->data_curr = chunk->data; + mi->data_last = chunk->data + (chunk_size - 1); + data_curr_next = mi->data_curr + (1 + data_offset); + } + + BLI_assert(data_curr_next <= mi->data_last); + + BLI_memiter_elem *elem = (BLI_memiter_elem *)mi->data_curr; + elem->size = elem_size; + mi->data_curr = data_curr_next; + +#ifdef USE_TERMINATE_PARANOID + memiter_set_rewind_offset(mi); +#endif + + mi->count += 1; + +#ifdef USE_TOTALLOC + mi->totalloc += elem_size; +#endif + + return elem->data; +} + +void *BLI_memiter_calloc(BLI_memiter *mi, uint elem_size) +{ + void *data = BLI_memiter_alloc(mi, elem_size); + memset(data, 0, elem_size); + return data; +} + +void BLI_memiter_alloc_from(BLI_memiter *mi, uint elem_size, const void *data_from) +{ + void *data = BLI_memiter_alloc(mi, elem_size); + memcpy(data, data_from, elem_size); +} + +static void memiter_free_data(BLI_memiter *mi) +{ + BLI_memiter_chunk *chunk = mi->head; + while (chunk) { + BLI_memiter_chunk *chunk_next = chunk->next; + MEM_freeN(chunk); + chunk = chunk_next; + } +} + +void BLI_memiter_destroy(BLI_memiter *mi) +{ + memiter_free_data(mi); + MEM_freeN(mi); +} + +void BLI_memiter_clear(BLI_memiter *mi) +{ + memiter_free_data(mi); + memiter_init(mi); +} + +uint BLI_memiter_count(const BLI_memiter *mi) +{ + return mi->count; +} + +/** \} */ + + +/* -------------------------------------------------------------------- */ + +/** \name Helper API's + * \{ */ + +/* Support direct lookup for first. */ +void *BLI_memiter_elem_first(BLI_memiter *mi) +{ + if (mi->head != NULL) { + BLI_memiter_chunk *chunk = mi->head; + BLI_memiter_elem *elem = (BLI_memiter_elem *)chunk->data; + return elem->data; + } + else { + return NULL; + } +} + +void *BLI_memiter_elem_first_size(BLI_memiter *mi, uint *r_size) +{ + if (mi->head != NULL) { + BLI_memiter_chunk *chunk = mi->head; + BLI_memiter_elem *elem = (BLI_memiter_elem *)chunk->data; + *r_size = (uint)elem->size; + return elem->data; + } + else { + return NULL; + } +} + +/** \} */ + + +/* -------------------------------------------------------------------- */ + +/** \name Iterator API's + * + * \note We could loop over elements until a NULL chunk is found, + * however this means every allocation needs to preemptively run + * #memiter_set_rewind_offset (see #USE_TERMINATE_PARANOID). + * Unless we have a call to finalize allocation (which complicates usage). + * So use a counter instead. + * + * \{ */ + +void BLI_memiter_iter_init(BLI_memiter *mi, BLI_memiter_handle *iter) +{ + iter->elem = mi->head ? (BLI_memiter_elem *)mi->head->data : NULL; + iter->elem_left = mi->count; +} + +bool BLI_memiter_iter_done(const BLI_memiter_handle *iter) +{ + return iter->elem_left != 0; +} + +BLI_INLINE void memiter_chunk_step(BLI_memiter_handle *iter) +{ + BLI_assert(iter->elem->size < 0); + BLI_memiter_chunk *chunk = (BLI_memiter_chunk *)(((data_t *)iter->elem) + iter->elem->size); + chunk = chunk->next; + iter->elem = chunk ? (BLI_memiter_elem *)chunk->data : NULL; + BLI_assert(iter->elem == NULL || iter->elem->size >= 0); +} + +void *BLI_memiter_iter_step_size(BLI_memiter_handle *iter, uint *r_size) +{ + if (iter->elem_left != 0) { + iter->elem_left -= 1; + if (UNLIKELY(iter->elem->size < 0)) { + memiter_chunk_step(iter); + } + BLI_assert(iter->elem->size >= 0); + uint size = (uint)iter->elem->size; + *r_size = size; /* <-- only difference */ + data_t *data = iter->elem->data; + iter->elem = (BLI_memiter_elem *)&data[data_offset_from_size(size)]; + return (void *)data; + } + else { + return NULL; + } +} + +void *BLI_memiter_iter_step(BLI_memiter_handle *iter) +{ + if (iter->elem_left != 0) { + iter->elem_left -= 1; + if (UNLIKELY(iter->elem->size < 0)) { + memiter_chunk_step(iter); + } + BLI_assert(iter->elem->size >= 0); + uint size = (uint)iter->elem->size; + data_t *data = iter->elem->data; + iter->elem = (BLI_memiter_elem *)&data[data_offset_from_size(size)]; + return (void *)data; + } + else { + return NULL; + } +} + +/** \} */ diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index 8d2d80c2a35..6574c001a23 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -314,6 +314,21 @@ MINLINE int signum_i(float a) else return 0; } +/** Returns number of (base ten) *significant* digits of integer part of given float + * (negative in case of decimal-only floats, 0.01 returns -1 e.g.). */ +MINLINE int integer_digits_f(const float f) +{ + return (f == 0.0f) ? 0 : (int)floor(log10(fabs(f))) + 1; +} + +/** Returns number of (base ten) *significant* digits of integer part of given double + * (negative in case of decimal-only floats, 0.01 returns -1 e.g.). */ +MINLINE int integer_digits_d(const double d) +{ + return (d == 0.0) ? 0 : (int)floor(log10(fabs(d))) + 1; +} + + /* Internal helpers for SSE2 implementation. * * NOTE: Are to be called ONLY from inside `#ifdef __SSE2__` !!! diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 7677d545e07..33e4dec107f 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -341,20 +341,20 @@ void mul_m4_m3m4(float m1[4][4], const float m3_[3][3], const float m2_[4][4]) * \{ */ void _va_mul_m3_series_3( float r[3][3], - float m1[3][3], float m2[3][3]) + const float m1[3][3], const float m2[3][3]) { mul_m3_m3m3(r, m1, m2); } void _va_mul_m3_series_4( float r[3][3], - float m1[3][3], float m2[3][3], float m3[3][3]) + const float m1[3][3], const float m2[3][3], const float m3[3][3]) { mul_m3_m3m3(r, m1, m2); mul_m3_m3m3(r, r, m3); } void _va_mul_m3_series_5( float r[3][3], - float m1[3][3], float m2[3][3], float m3[3][3], float m4[3][3]) + const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3]) { mul_m3_m3m3(r, m1, m2); mul_m3_m3m3(r, r, m3); @@ -362,8 +362,8 @@ void _va_mul_m3_series_5( } void _va_mul_m3_series_6( float r[3][3], - float m1[3][3], float m2[3][3], float m3[3][3], float m4[3][3], - float m5[3][3]) + const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3], + const float m5[3][3]) { mul_m3_m3m3(r, m1, m2); mul_m3_m3m3(r, r, m3); @@ -372,8 +372,8 @@ void _va_mul_m3_series_6( } void _va_mul_m3_series_7( float r[3][3], - float m1[3][3], float m2[3][3], float m3[3][3], float m4[3][3], - float m5[3][3], float m6[3][3]) + const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3], + const float m5[3][3], const float m6[3][3]) { mul_m3_m3m3(r, m1, m2); mul_m3_m3m3(r, r, m3); @@ -383,8 +383,8 @@ void _va_mul_m3_series_7( } void _va_mul_m3_series_8( float r[3][3], - float m1[3][3], float m2[3][3], float m3[3][3], float m4[3][3], - float m5[3][3], float m6[3][3], float m7[3][3]) + const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3], + const float m5[3][3], const float m6[3][3], const float m7[3][3]) { mul_m3_m3m3(r, m1, m2); mul_m3_m3m3(r, r, m3); @@ -395,8 +395,8 @@ void _va_mul_m3_series_8( } void _va_mul_m3_series_9( float r[3][3], - float m1[3][3], float m2[3][3], float m3[3][3], float m4[3][3], - float m5[3][3], float m6[3][3], float m7[3][3], float m8[3][3]) + const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3], + const float m5[3][3], const float m6[3][3], const float m7[3][3], const float m8[3][3]) { mul_m3_m3m3(r, m1, m2); mul_m3_m3m3(r, r, m3); @@ -412,20 +412,20 @@ void _va_mul_m3_series_9( * \{ */ void _va_mul_m4_series_3( float r[4][4], - float m1[4][4], float m2[4][4]) + const float m1[4][4], const float m2[4][4]) { mul_m4_m4m4(r, m1, m2); } void _va_mul_m4_series_4( float r[4][4], - float m1[4][4], float m2[4][4], float m3[4][4]) + const float m1[4][4], const float m2[4][4], const float m3[4][4]) { mul_m4_m4m4(r, m1, m2); mul_m4_m4m4(r, r, m3); } void _va_mul_m4_series_5( float r[4][4], - float m1[4][4], float m2[4][4], float m3[4][4], float m4[4][4]) + const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4]) { mul_m4_m4m4(r, m1, m2); mul_m4_m4m4(r, r, m3); @@ -433,8 +433,8 @@ void _va_mul_m4_series_5( } void _va_mul_m4_series_6( float r[4][4], - float m1[4][4], float m2[4][4], float m3[4][4], float m4[4][4], - float m5[4][4]) + const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4], + const float m5[4][4]) { mul_m4_m4m4(r, m1, m2); mul_m4_m4m4(r, r, m3); @@ -443,8 +443,8 @@ void _va_mul_m4_series_6( } void _va_mul_m4_series_7( float r[4][4], - float m1[4][4], float m2[4][4], float m3[4][4], float m4[4][4], - float m5[4][4], float m6[4][4]) + const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4], + const float m5[4][4], const float m6[4][4]) { mul_m4_m4m4(r, m1, m2); mul_m4_m4m4(r, r, m3); @@ -454,8 +454,8 @@ void _va_mul_m4_series_7( } void _va_mul_m4_series_8( float r[4][4], - float m1[4][4], float m2[4][4], float m3[4][4], float m4[4][4], - float m5[4][4], float m6[4][4], float m7[4][4]) + const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4], + const float m5[4][4], const float m6[4][4], const float m7[4][4]) { mul_m4_m4m4(r, m1, m2); mul_m4_m4m4(r, r, m3); @@ -466,8 +466,8 @@ void _va_mul_m4_series_8( } void _va_mul_m4_series_9( float r[4][4], - float m1[4][4], float m2[4][4], float m3[4][4], float m4[4][4], - float m5[4][4], float m6[4][4], float m7[4][4], float m8[4][4]) + const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4], + const float m5[4][4], const float m6[4][4], const float m7[4][4], const float m8[4][4]) { mul_m4_m4m4(r, m1, m2); mul_m4_m4m4(r, r, m3); diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index 347640aae0d..86c24307ae2 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -1395,9 +1395,9 @@ static float voronoi_CrS(float x, float y, float z) static float cellNoiseU(float x, float y, float z) { /* avoid precision issues on unit coordinates */ - x = (x + 0.000001f)*0.999999f; - y = (y + 0.000001f)*0.999999f; - z = (z + 0.000001f)*0.999999f; + x = (x + 0.000001f)*1.00001f; + y = (y + 0.000001f)*1.00001f; + z = (z + 0.000001f)*1.00001f; int xi = (int)(floor(x)); int yi = (int)(floor(y)); @@ -1417,9 +1417,9 @@ float cellNoise(float x, float y, float z) void cellNoiseV(float x, float y, float z, float ca[3]) { /* avoid precision issues on unit coordinates */ - x = (x + 0.000001f)*0.999999f; - y = (y + 0.000001f)*0.999999f; - z = (z + 0.000001f)*0.999999f; + x = (x + 0.000001f)*1.00001f; + y = (y + 0.000001f)*1.00001f; + z = (z + 0.000001f)*1.00001f; int xi = (int)(floor(x)); int yi = (int)(floor(y)); diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index 0a678cfe6f8..61d1aa18b3c 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -81,6 +81,10 @@ if(WITH_INTERNATIONAL) add_definitions(-DWITH_INTERNATIONAL) endif() +if(WITH_CLAY_ENGINE) + add_definitions(-DWITH_CLAY_ENGINE) +endif() + if(WITH_CODEC_FFMPEG) add_definitions(-DWITH_FFMPEG) endif() diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9fdb0152dfe..e71f593b530 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2222,6 +2222,7 @@ static void direct_link_id(FileData *fd, ID *id) /* this case means the data was written incorrectly, it should not happen */ IDP_DirectLinkGroup_OrFree(&id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); } + id->py_instance = NULL; } /* ************ READ CurveMapping *************** */ diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index cb7c46d24f3..cabb1409603 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -1659,7 +1659,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } FOREACH_NODETREE_END } - { + if (!MAIN_VERSION_ATLEAST(main, 279, 0)) { for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { if (scene->r.im_format.exr_codec == R_IMF_EXR_CODEC_DWAB) { scene->r.im_format.exr_codec = R_IMF_EXR_CODEC_DWAA; @@ -1697,7 +1697,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) void do_versions_after_linking_270(Main *main) { /* To be added to next subversion bump! */ - { + if (!MAIN_VERSION_ATLEAST(main, 279, 0)) { FOREACH_NODETREE(main, ntree, id) { if (ntree->type == NTREE_COMPOSIT) { ntreeSetTypes(NULL, ntree); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index d76a121376c..1c7ecc9ce3b 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -345,7 +345,18 @@ static void do_version_layer_collections_idproperties(ListBase *lb) void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main) { + if (!MAIN_VERSION_ATLEAST(main, 280, 0)) { + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + if (STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER)) { +#ifdef WITH_CLAY_ENGINE + BLI_strncpy(scene->r.engine, RE_engine_id_BLENDER_CLAY, sizeof(scene->r.engine)); +#else + BLI_strncpy(scene->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(scene->r.engine)); +#endif + } + } + if (!DNA_struct_elem_find(fd->filesdna, "Scene", "ListBase", "render_layers")) { for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { /* Master Collection */ diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index 50f96a6d438..cea3adaf614 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -61,6 +61,9 @@ void BLO_update_defaults_userpref_blend(void) U.uiflag |= USER_QUIT_PROMPT; U.uiflag |= USER_CONTINUOUS_MOUSE; + /* See T45301 */ + U.uiflag |= USER_LOCK_CURSOR_ADJUST; + U.versions = 1; U.savetime = 2; diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 4fe14fdf5c9..6b22fd0a85c 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -2415,7 +2415,8 @@ static void bmesh_kernel_vert_separate__cleanup(BMesh *bm, LinkNode *edges_separ /* don't visit again */ n_prev->next = n_step->next; } - } while ((n_prev = n_step), + } while ((void) + (n_prev = n_step), (n_step = n_step->next)); } while ((n_orig = n_orig->next) && n_orig->next); diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h index 4161fbe90fb..4dcf97e3f35 100644 --- a/source/blender/bmesh/intern/bmesh_private.h +++ b/source/blender/bmesh/intern/bmesh_private.h @@ -44,13 +44,14 @@ # define BM_CHECK_ELEMENT(el) (void)(el) #else int bmesh_elem_check(void *element, const char htype); -# define BM_CHECK_ELEMENT(el) \ +# define BM_CHECK_ELEMENT(el) { \ if (bmesh_elem_check(el, ((BMHeader *)el)->htype)) { \ printf("check_element failure, with code %i on line %i in file\n" \ " \"%s\"\n\n", \ bmesh_elem_check(el, ((BMHeader *)el)->htype), \ __LINE__, __FILE__); \ - } (void)0 + } \ +} ((void)0) #endif int bmesh_radial_length(const BMLoop *l); diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c index cca0f7387cd..d8f83d786b4 100644 --- a/source/blender/bmesh/operators/bmo_primitive.c +++ b/source/blender/bmesh/operators/bmo_primitive.c @@ -839,7 +839,7 @@ void BM_mesh_calc_uvs_grid( const float dx = 1.0f / (float)(x_segments - 1); const float dy = 1.0f / (float)(y_segments - 1); float x = 0.0f; - float y = 0.0f; + float y = dy; int loop_index; @@ -854,16 +854,16 @@ void BM_mesh_calc_uvs_grid( switch (loop_index) { case 0: - x += dx; + y -= dy; break; case 1: - y += dy; + x += dx; break; case 2: - x -= dx; + y += dy; break; case 3: - y -= dy; + x -= dx; break; default: break; diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 6673c5d25cf..92b65b94fb8 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -234,7 +234,7 @@ static bool nearly_parallel(const float d1[3], const float d2[3]) float ang; ang = angle_v3v3(d1, d2); - return (fabsf(ang) < BEVEL_EPSILON_ANG) || (fabsf(ang - M_PI) < BEVEL_EPSILON_ANG); + return (fabsf(ang) < BEVEL_EPSILON_ANG) || (fabsf(ang - (float)M_PI) < BEVEL_EPSILON_ANG); } /* Make a new BoundVert of the given kind, insert it at the end of the circular linked diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp index 707aaea0b65..42dde0be266 100644 --- a/source/blender/collada/AnimationExporter.cpp +++ b/source/blender/collada/AnimationExporter.cpp @@ -34,10 +34,11 @@ void forEachObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) } } -bool AnimationExporter::exportAnimations(Scene *sce) +bool AnimationExporter::exportAnimations(struct EvaluationContext *eval_ctx, Scene *sce) { bool has_animations = hasAnimations(sce); if (has_animations) { + this->eval_ctx = eval_ctx; this->scene = sce; openLibrary(); @@ -480,7 +481,7 @@ void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, B if (flag & ARM_RESTPOS) { arm->flag &= ~ARM_RESTPOS; - BKE_pose_where_is(scene, ob_arm); + BKE_pose_where_is(eval_ctx, scene, ob_arm); } if (fra.size()) { @@ -489,7 +490,7 @@ void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, B if (flag & ARM_RESTPOS) arm->flag = flag; - BKE_pose_where_is(scene, ob_arm); + BKE_pose_where_is(eval_ctx, scene, ob_arm); } void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_arm, Bone *bone) @@ -530,7 +531,7 @@ void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_ addSampler(sampler); - std::string target = translate_id(bone_name) + "/transform"; + std::string target = get_joint_id(bone, ob_arm) + "/transform"; addChannel(COLLADABU::URI(empty, sampler_id), target); closeAnimation(); @@ -945,10 +946,10 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj if (pchan->flag & POSE_CHAIN) { enable_fcurves(ob->adt->action, NULL); BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_ALL); - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(eval_ctx, scene, ob); } else { - BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1); + BKE_pose_where_is_bone(eval_ctx, scene, ob, pchan, ctime, 1); } // compute bone local mat @@ -1438,7 +1439,7 @@ void AnimationExporter::sample_and_write_bone_animation(Object *ob_arm, Bone *bo // exit rest position if (flag & ARM_RESTPOS) { arm->flag &= ~ARM_RESTPOS; - BKE_pose_where_is(scene, ob_arm); + BKE_pose_where_is(eval_ctx, scene, ob_arm); } //v array will hold all values which will be exported. if (fra.size()) { @@ -1468,7 +1469,7 @@ void AnimationExporter::sample_and_write_bone_animation(Object *ob_arm, Bone *bo // restore restpos if (flag & ARM_RESTPOS) arm->flag = flag; - BKE_pose_where_is(scene, ob_arm); + BKE_pose_where_is(eval_ctx, scene, ob_arm); } void AnimationExporter::sample_animation(float *v, std::vector<float> &frames, int type, Bone *bone, Object *ob_arm, bPoseChannel *pchan) @@ -1493,7 +1494,7 @@ void AnimationExporter::sample_animation(float *v, std::vector<float> &frames, i BKE_animsys_evaluate_animdata(scene, &ob_arm->id, ob_arm->adt, ctime, ADT_RECALC_ANIM); - BKE_pose_where_is_bone(scene, ob_arm, pchan, ctime, 1); + BKE_pose_where_is_bone(eval_ctx, scene, ob_arm, pchan, ctime, 1); // compute bone local mat if (bone->parent) { @@ -1554,7 +1555,7 @@ void AnimationExporter::calc_ob_mat_at_time(Object *ob, float ctime , float mat[ if (obtar) { BKE_animsys_evaluate_animdata(scene, &obtar->id, obtar->adt, ctime, ADT_RECALC_ANIM); - BKE_object_where_is_calc_time(scene, obtar, ctime); + BKE_object_where_is_calc_time(eval_ctx, scene, obtar, ctime); } } @@ -1562,7 +1563,7 @@ void AnimationExporter::calc_ob_mat_at_time(Object *ob, float ctime , float mat[ cti->flush_constraint_targets(con, &targets, 1); } } - BKE_object_where_is_calc_time(scene, ob, ctime); + BKE_object_where_is_calc_time(eval_ctx, scene, ob, ctime); copy_m4_m4(mat, ob->obmat); } diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h index 4736361ad13..d21f3a74ceb 100644 --- a/source/blender/collada/AnimationExporter.h +++ b/source/blender/collada/AnimationExporter.h @@ -79,12 +79,13 @@ extern "C" #include <vector> #include <algorithm> // std::find - +struct EvaluationContext; class AnimationExporter: COLLADASW::LibraryAnimations { private: Scene *scene; + struct EvaluationContext *eval_ctx; COLLADASW::StreamWriter *sw; public: @@ -94,7 +95,7 @@ public: { this->sw = sw; } - bool exportAnimations(Scene *sce); + bool exportAnimations(struct EvaluationContext *eval_ctx, Scene *sce); // called for each exported object void operator() (Object *ob); diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index 9348f3b3285..ad5ffadebc5 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -62,8 +62,8 @@ ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSett } // write bone nodes -void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce, - SceneExporter *se, +void ArmatureExporter::add_armature_bones(EvaluationContext *eval_ctx, Object *ob_arm, + Scene *sce, SceneExporter *se, std::list<Object *>& child_objects) { // write bone nodes @@ -77,7 +77,7 @@ void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce, for (Bone *bone = (Bone *)armature->bonebase.first; bone; bone = bone->next) { // start from root bones if (!bone->parent) - add_bone_node(bone, ob_arm, sce, se, child_objects); + add_bone_node(eval_ctx, bone, ob_arm, sce, se, child_objects); } if (!is_edited) { @@ -157,7 +157,7 @@ void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vector<O #endif // parent_mat is armature-space -void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, +void ArmatureExporter::add_bone_node(EvaluationContext *eval_ctx, Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se, std::list<Object *>& child_objects) { @@ -231,7 +231,7 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, mul_m4_m4m4((*i)->parentinv, temp, (*i)->parentinv); } - se->writeNodes(*i, sce); + se->writeNodes(eval_ctx, *i, sce); copy_m4_m4((*i)->parentinv, backup_parinv); child_objects.erase(i++); @@ -240,13 +240,13 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, } for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - add_bone_node(child, ob_arm, sce, se, child_objects); + add_bone_node(eval_ctx, child, ob_arm, sce, se, child_objects); } node.end(); } else { for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - add_bone_node(child, ob_arm, sce, se, child_objects); + add_bone_node(eval_ctx, child, ob_arm, sce, se, child_objects); } } } diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h index d271b505aa9..f0582e97643 100644 --- a/source/blender/collada/ArmatureExporter.h +++ b/source/blender/collada/ArmatureExporter.h @@ -60,7 +60,7 @@ public: ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); // write bone nodes - void add_armature_bones(Object *ob_arm, Scene *sce, SceneExporter *se, + void add_armature_bones(struct EvaluationContext *eval_ctx, Object *ob_arm, Scene *sce, SceneExporter *se, std::list<Object *>& child_objects); bool add_instance_controller(Object *ob); @@ -85,7 +85,7 @@ private: // Scene, SceneExporter and the list of child_objects // are required for writing bone parented objects - void add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se, + void add_bone_node(struct EvaluationContext *eval_ctx, Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se, std::list<Object *>& child_objects); void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node); diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp index 1c2642e8313..3dd2490edfc 100644 --- a/source/blender/collada/ControllerExporter.cpp +++ b/source/blender/collada/ControllerExporter.cpp @@ -104,8 +104,9 @@ bool ControllerExporter::add_instance_controller(Object *ob) return true; } -void ControllerExporter::export_controllers(Scene *sce) +void ControllerExporter::export_controllers(struct EvaluationContext *eval_ctx, Scene *sce) { + this->eval_ctx = eval_ctx; scene = sce; openLibrary(); @@ -197,7 +198,7 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm) bool use_instantiation = this->export_settings->use_object_instantiation; Mesh *me; - me = bc_get_mesh_copy(scene, + me = bc_get_mesh_copy(eval_ctx, scene, ob, this->export_settings->export_mesh_type, this->export_settings->apply_modifiers, @@ -299,7 +300,7 @@ void ControllerExporter::export_morph_controller(Object *ob, Key *key) bool use_instantiation = this->export_settings->use_object_instantiation; Mesh *me; - me = bc_get_mesh_copy(scene, + me = bc_get_mesh_copy(eval_ctx, scene, ob, this->export_settings->export_mesh_type, this->export_settings->apply_modifiers, @@ -494,7 +495,7 @@ std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, ListBas // put armature in rest position if (!(arm->flag & ARM_RESTPOS)) { arm->flag |= ARM_RESTPOS; - BKE_pose_where_is(scene, ob_arm); + BKE_pose_where_is(eval_ctx, scene, ob_arm); } for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) { @@ -542,7 +543,7 @@ std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, ListBas // back from rest positon if (!(flag & ARM_RESTPOS)) { arm->flag = flag; - BKE_pose_where_is(scene, ob_arm); + BKE_pose_where_is(eval_ctx, scene, ob_arm); } source.finish(); diff --git a/source/blender/collada/ControllerExporter.h b/source/blender/collada/ControllerExporter.h index 80b858ca6dd..c96015c7817 100644 --- a/source/blender/collada/ControllerExporter.h +++ b/source/blender/collada/ControllerExporter.h @@ -54,6 +54,7 @@ #include "BKE_key.h" +struct EvaluationContext; class SceneExporter; class ControllerExporter : public COLLADASW::LibraryControllers, protected TransformWriter, protected InstanceWriter @@ -65,11 +66,12 @@ public: bool add_instance_controller(Object *ob); - void export_controllers(Scene *sce); + void export_controllers(struct EvaluationContext *eval_ctx, Scene *sce); void operator()(Object *ob); private: + struct EvaluationContext *eval_ctx; Scene *scene; UnitConverter converter; const ExportSettings *export_settings; diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index bd32e989ae3..46628ed028e 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -179,7 +179,7 @@ static COLLADABU::NativeString make_temp_filepath(const char *name, const char * // COLLADA allows this through multiple <channel>s in <animation>. // For this to work, we need to know objects that use a certain action. -int DocumentExporter::exportCurrentScene(Scene *sce) +int DocumentExporter::exportCurrentScene(EvaluationContext *eval_ctx, Scene *sce) { PointerRNA sceneptr, unit_settings; PropertyRNA *system; /* unused , *scale; */ @@ -285,19 +285,19 @@ int DocumentExporter::exportCurrentScene(Scene *sce) // <library_geometries> if (bc_has_object_type(export_set, OB_MESH)) { GeometryExporter ge(writer, this->export_settings); - ge.exportGeom(sce); + ge.exportGeom(eval_ctx, sce); } // <library_animations> AnimationExporter ae(writer, this->export_settings); - bool has_animations = ae.exportAnimations(sce); + bool has_animations = ae.exportAnimations(eval_ctx, sce); // <library_controllers> ArmatureExporter arm_exporter(writer, this->export_settings); ControllerExporter controller_exporter(writer, this->export_settings); if (bc_has_object_type(export_set, OB_ARMATURE) || this->export_settings->include_shapekeys) { - controller_exporter.export_controllers(sce); + controller_exporter.export_controllers(eval_ctx, sce); } // <library_visual_scenes> @@ -316,7 +316,7 @@ int DocumentExporter::exportCurrentScene(Scene *sce) se.setExportTransformationType(this->export_settings->export_transformation_type); } - se.exportScene(sce); + se.exportScene(eval_ctx, sce); // <scene> std::string scene_name(translate_id(id_name(sce))); diff --git a/source/blender/collada/DocumentExporter.h b/source/blender/collada/DocumentExporter.h index 6e3c1ecd7cd..1d32c87610e 100644 --- a/source/blender/collada/DocumentExporter.h +++ b/source/blender/collada/DocumentExporter.h @@ -39,7 +39,7 @@ class DocumentExporter { public: DocumentExporter(const ExportSettings *export_settings); - int exportCurrentScene(Scene *sce); + int exportCurrentScene(struct EvaluationContext *eval_ctx, Scene *sce); void exportScenes(const char *filename); private: const ExportSettings *export_settings; diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 7c7c57f3305..715f0ab5370 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -57,10 +57,11 @@ GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSett { } -void GeometryExporter::exportGeom(Scene *sce) +void GeometryExporter::exportGeom(struct EvaluationContext *eval_ctx, Scene *sce) { openLibrary(); + mEvalCtx = eval_ctx; mScene = sce; GeometryFunctor gf; gf.forEachMeshObjectInExportSet<GeometryExporter>(sce, *this, this->export_settings->export_set); @@ -76,7 +77,7 @@ void GeometryExporter::operator()(Object *ob) #endif bool use_instantiation = this->export_settings->use_object_instantiation; - Mesh *me = bc_get_mesh_copy( mScene, + Mesh *me = bc_get_mesh_copy(mEvalCtx, mScene, ob, this->export_settings->export_mesh_type, this->export_settings->apply_modifiers, diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h index 69d1067e6f4..91062ef8f19 100644 --- a/source/blender/collada/GeometryExporter.h +++ b/source/blender/collada/GeometryExporter.h @@ -46,6 +46,8 @@ #include "BKE_key.h" +struct EvaluationContext; + extern Object *bc_get_highest_selected_ancestor_or_self(Object *ob); class Normal @@ -72,12 +74,13 @@ class GeometryExporter : COLLADASW::LibraryGeometries Normal n; + struct EvaluationContext *mEvalCtx; Scene *mScene; public: GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); - void exportGeom(Scene *sce); + void exportGeom(struct EvaluationContext *eval_ctx, Scene *sce); void operator()(Object *ob); diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp index 30cd6ddf197..1447cd7f72f 100644 --- a/source/blender/collada/SceneExporter.cpp +++ b/source/blender/collada/SceneExporter.cpp @@ -43,17 +43,17 @@ void SceneExporter::setExportTransformationType(BC_export_transformation_type tr this->transformation_type = transformation_type; } -void SceneExporter::exportScene(Scene *sce) +void SceneExporter::exportScene(EvaluationContext *eval_ctx, Scene *sce) { // <library_visual_scenes> <visual_scene> std::string id_naming = id_name(sce); openVisualScene(translate_id(id_naming), id_naming); - exportHierarchy(sce); + exportHierarchy(eval_ctx, sce); closeVisualScene(); closeLibrary(); } -void SceneExporter::exportHierarchy(Scene *sce) +void SceneExporter::exportHierarchy(EvaluationContext *eval_ctx, Scene *sce) { LinkNode *node; std::vector<Object *> base_objects; @@ -85,13 +85,13 @@ void SceneExporter::exportHierarchy(Scene *sce) Object *ob = base_objects[index]; if (bc_is_marked(ob)) { bc_remove_mark(ob); - writeNodes(ob, sce); + writeNodes(eval_ctx, ob, sce); } } } -void SceneExporter::writeNodes(Object *ob, Scene *sce) +void SceneExporter::writeNodes(EvaluationContext *eval_ctx, Object *ob, Scene *sce) { // Add associated armature first if available bool armature_exported = false; @@ -100,7 +100,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) armature_exported = bc_is_in_Export_set(this->export_settings->export_set, ob_arm); if (armature_exported && bc_is_marked(ob_arm)) { bc_remove_mark(ob_arm); - writeNodes(ob_arm, sce); + writeNodes(eval_ctx, ob_arm, sce); armature_exported = true; } } @@ -159,7 +159,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) // <instance_controller> else if (ob->type == OB_ARMATURE) { - arm_exporter->add_armature_bones(ob, sce, this, child_objects); + arm_exporter->add_armature_bones(eval_ctx, ob, sce, this, child_objects); } // <instance_camera> @@ -237,7 +237,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) for (std::list<Object *>::iterator i = child_objects.begin(); i != child_objects.end(); ++i) { if (bc_is_marked(*i)) { bc_remove_mark(*i); - writeNodes(*i, sce); + writeNodes(eval_ctx, *i, sce); } } diff --git a/source/blender/collada/SceneExporter.h b/source/blender/collada/SceneExporter.h index c7c15dba2cb..8dd6da4db05 100644 --- a/source/blender/collada/SceneExporter.h +++ b/source/blender/collada/SceneExporter.h @@ -96,15 +96,15 @@ class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter, { public: SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings); - void exportScene(Scene *sce); + void exportScene(struct EvaluationContext *eval_ctx, Scene *sce); void setExportTransformationType(BC_export_transformation_type transformation_type); private: BC_export_transformation_type transformation_type; // required for writeNodes() for bone-parented objects friend class ArmatureExporter; - void exportHierarchy(Scene *sce); - void writeNodes(Object *ob, Scene *sce); + void exportHierarchy(struct EvaluationContext *eval_ctx, Scene *sce); + void writeNodes(struct EvaluationContext *eval_ctx, Object *ob, Scene *sce); ArmatureExporter *arm_exporter; const ExportSettings *export_settings; diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp index b7eeff3b074..84817d76073 100644 --- a/source/blender/collada/TransformWriter.cpp +++ b/source/blender/collada/TransformWriter.cpp @@ -61,7 +61,8 @@ void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[4][4], } } -void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob, BC_export_transformation_type transformation_type) +void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob, + BC_export_transformation_type transformation_type) { #if 0 float rot[3], loc[3], scale[3]; diff --git a/source/blender/collada/TransformWriter.h b/source/blender/collada/TransformWriter.h index 5bb13d4aac9..580430911f7 100644 --- a/source/blender/collada/TransformWriter.h +++ b/source/blender/collada/TransformWriter.h @@ -41,7 +41,8 @@ class TransformWriter protected: void add_node_transform(COLLADASW::Node& node, float mat[4][4], float parent_mat[4][4]); - void add_node_transform_ob(COLLADASW::Node& node, Object *ob, BC_export_transformation_type transformation_type); + void add_node_transform_ob(COLLADASW::Node& node, Object *ob, + BC_export_transformation_type transformation_type); void add_node_transform_identity(COLLADASW::Node& node); diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index 9cb0b414721..5c5b2ec2dc2 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -67,7 +67,8 @@ int collada_import(bContext *C, return 0; } -int collada_export(Scene *sce, +int collada_export(EvaluationContext *eval_ctx, + Scene *sce, SceneLayer *scene_layer, const char *filepath, @@ -140,7 +141,7 @@ int collada_export(Scene *sce, } DocumentExporter exporter(&export_settings); - int status = exporter.exportCurrentScene(sce); + int status = exporter.exportCurrentScene(eval_ctx, sce); BLI_linklist_free(export_settings.export_set, NULL); diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index 9aba51ef18a..c42338002cd 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -49,6 +49,7 @@ typedef enum BC_export_transformation_type { struct bContext; struct Scene; struct SceneLayer; +struct EvaluationContext; /* * both return 1 on success, 0 on error @@ -63,7 +64,8 @@ int collada_import(struct bContext *C, int keep_bind_info); -int collada_export(struct Scene *sce, +int collada_export(struct EvaluationContext *eval_ctx, + struct Scene *sce, struct SceneLayer *scene_layer, const char *filepath, int apply_modifiers, diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index 0f39b27316c..85ac0eb8d3d 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -93,6 +93,9 @@ int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space) { Object workob; Scene *sce = CTX_data_scene(C); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); if (!par || bc_test_parent_loop(par, ob)) return false; @@ -105,7 +108,7 @@ int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space) if (is_parent_space) { float mat[4][4]; // calc par->obmat - BKE_object_where_is_calc(sce, par); + BKE_object_where_is_calc(&eval_ctx, sce, par); // move child obmat into world space mul_m4_m4m4(mat, par->obmat, ob->obmat); @@ -116,7 +119,7 @@ int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space) BKE_object_apply_mat4(ob, ob->obmat, 0, 0); // compute parentinv - BKE_object_workob_calc_parent(sce, ob, &workob); + BKE_object_workob_calc_parent(&eval_ctx, sce, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA); @@ -144,7 +147,7 @@ Object *bc_add_object(Scene *scene, int type, const char *name) return ob; } -Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate) +Mesh *bc_get_mesh_copy(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate) { Mesh *tmpmesh; CustomDataMask mask = CD_MASK_MESH; @@ -154,12 +157,12 @@ Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh switch (export_mesh_type) { case BC_MESH_TYPE_VIEW: { - dm = mesh_create_derived_view(scene, ob, mask); + dm = mesh_create_derived_view(eval_ctx, scene, ob, mask); break; } case BC_MESH_TYPE_RENDER: { - dm = mesh_create_derived_render(scene, ob, mask); + dm = mesh_create_derived_render(eval_ctx, scene, ob, mask); break; } } diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 38c0bd5096a..df972c5b89c 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -60,13 +60,15 @@ extern "C" { #include "ExportSettings.h" #include "collada_internal.h" +struct EvaluationContext; + typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex *> > TexIndexTextureArrayMap; extern float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index); extern int bc_test_parent_loop(Object *par, Object *ob); extern int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space = true); extern Object *bc_add_object(Scene *scene, int type, const char *name); -extern Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate); +extern Mesh *bc_get_mesh_copy(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate); extern Object *bc_get_assigned_armature(Object *ob); extern Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob); diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp index 57aa3a1bac2..94f407dad86 100644 --- a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp @@ -65,10 +65,10 @@ void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTil } } // // B - for (y = tbuf1->getHeight() - 1 && (!breaked); y >= 0; y--) { + for (y = this->getHeight() - 1; y >= 0 && (!breaked); y--) { ym = y - i; yp = y + i; - for (x = tbuf1->getWidth() - 1; x >= 0; x--) { + for (x = this->getWidth() - 1; x >= 0; x--) { xm = x - i; xp = x + i; tbuf1->read(c, x, y); diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cpp b/source/blender/compositor/operations/COM_RenderLayersProg.cpp index f2f1b211a97..26654b31e16 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersProg.cpp @@ -246,4 +246,4 @@ void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float unsigned int offset = (iy * this->getWidth() + ix); output[0] = inputBuffer[offset]; } -}
\ No newline at end of file +} diff --git a/source/blender/datatoc/datatoc.c b/source/blender/datatoc/datatoc.c index 4e49a9a7694..ffccca98f99 100644 --- a/source/blender/datatoc/datatoc.c +++ b/source/blender/datatoc/datatoc.c @@ -91,6 +91,11 @@ int main(int argc, char **argv) } fprintf(fpout, "/* DataToC output of file <%s> */\n\n", argv[1]); + + /* Quiet 'missing-variable-declarations' warning. */ + fprintf(fpout, "extern int datatoc_%s_size;\n", argv[1]); + fprintf(fpout, "extern char datatoc_%s[];\n\n", argv[1]); + fprintf(fpout, "int datatoc_%s_size = %d;\n", argv[1], (int)size); fprintf(fpout, "char datatoc_%s[] = {\n", argv[1]); while (size--) { diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h index 9347a29b14a..540367712f1 100644 --- a/source/blender/depsgraph/DEG_depsgraph.h +++ b/source/blender/depsgraph/DEG_depsgraph.h @@ -65,6 +65,14 @@ struct Main; struct PointerRNA; struct PropertyRNA; +struct Scene; +struct SceneLayer; + +typedef enum eEvaluationMode { + DAG_EVAL_VIEWPORT = 0, /* evaluate for OpenGL viewport */ + DAG_EVAL_PREVIEW = 1, /* evaluate for render with preview settings */ + DAG_EVAL_RENDER = 2, /* evaluate for render purposes */ +} eEvaluationMode; /* Dependency graph evaluation context * @@ -72,15 +80,11 @@ struct PropertyRNA; * which is needed for it's evaluation, */ typedef struct EvaluationContext { - int mode; + eEvaluationMode mode; float ctime; -} EvaluationContext; -typedef enum eEvaluationMode { - DAG_EVAL_VIEWPORT = 0, /* evaluate for OpenGL viewport */ - DAG_EVAL_PREVIEW = 1, /* evaluate for render with preview settings */ - DAG_EVAL_RENDER = 2, /* evaluate for render purposes */ -} eEvaluationMode; + struct SceneLayer *scene_layer; +} EvaluationContext; /* DagNode->eval_flags */ enum { @@ -136,13 +140,6 @@ void DEG_graph_on_visible_update(struct Main *bmain, struct Scene *scene); /* Update all dependency graphs when visible scenes/layers changes. */ void DEG_on_visible_update(struct Main *bmain, const bool do_time); -/* Tag node(s) associated with changed data for later updates */ -void DEG_graph_id_tag_update(struct Main *bmain, - Depsgraph *graph, - struct ID *id); -void DEG_graph_data_tag_update(Depsgraph *graph, const struct PointerRNA *ptr); -void DEG_graph_property_tag_update(Depsgraph *graph, const struct PointerRNA *ptr, const struct PropertyRNA *prop); - /* Tag given ID for an update in all the dependency graphs. */ enum { /* Object transformation changed, corresponds to OB_RECALC_OB. */ @@ -164,6 +161,11 @@ enum { /* Update copy on write component without flushing down the road. */ DEG_TAG_COPY_ON_WRITE = (1 << 8), + + /* Tag shading components for update. + * Only parameters of material changed). + */ + DEG_TAG_SHADING_UPDATE = (1 << 9), }; void DEG_id_tag_update(struct ID *id, int flag); void DEG_id_tag_update_ex(struct Main *bmain, @@ -175,7 +177,7 @@ void DEG_id_tag_update_ex(struct Main *bmain, * Used by all sort of render engines to quickly check if * IDs of a given type need to be checked for update. */ -void DEG_id_type_tag(struct Main *bmain, short idtype); +void DEG_id_type_tag(struct Main *bmain, short id_type); void DEG_ids_clear_recalc(struct Main *bmain); @@ -197,13 +199,18 @@ void DEG_ids_check_recalc(struct Main *bmain, /* Evaluation Context ---------------------------- */ /* Create new evaluation context. */ -struct EvaluationContext *DEG_evaluation_context_new(int mode); +struct EvaluationContext *DEG_evaluation_context_new(eEvaluationMode mode); /* Initialize evaluation context. * Used by the areas which currently overrides the context or doesn't have * access to a proper one. */ -void DEG_evaluation_context_init(struct EvaluationContext *eval_ctx, int mode); +void DEG_evaluation_context_init(struct EvaluationContext *eval_ctx, + eEvaluationMode mode); +void DEG_evaluation_context_init_from_scene(struct EvaluationContext *eval_ctx, + struct Scene *scene, + struct SceneLayer *scene_layer, + eEvaluationMode mode); /* Free evaluation context. */ void DEG_evaluation_context_free(struct EvaluationContext *eval_ctx); diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h index 8c3ddec40a4..0e29f24f454 100644 --- a/source/blender/depsgraph/DEG_depsgraph_build.h +++ b/source/blender/depsgraph/DEG_depsgraph_build.h @@ -42,6 +42,7 @@ struct Depsgraph; struct CacheFile; struct EffectorWeights; +struct EvaluationContext; struct Group; struct Main; struct ModifierData; diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h index 04584c07d4b..1020d4e606e 100644 --- a/source/blender/depsgraph/DEG_depsgraph_query.h +++ b/source/blender/depsgraph/DEG_depsgraph_query.h @@ -50,7 +50,7 @@ extern "C" { #endif /* Check if given ID type was tagged for update. */ -bool DEG_id_type_tagged(struct Main *bmain, short idtype); +bool DEG_id_type_tagged(struct Main *bmain, short id_type); /* Get additional evaluation flags for the given ID. */ short DEG_get_eval_flags_for_id(struct Depsgraph *graph, struct ID *id); diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index 92c79388657..deee2227f81 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -41,6 +41,8 @@ #include "intern/depsgraph_types.h" #include "intern/nodes/deg_node.h" +#include "DEG_depsgraph.h" + namespace DEG { void deg_graph_build_finalize(Depsgraph *graph) @@ -61,11 +63,9 @@ void deg_graph_build_finalize(Depsgraph *graph) id_node->tag_update(graph); } } - /* XXX: This is only so we've got proper COW IDs after rebuild. */ - /* TODO(sergey): Ideally we'll need to copy evaluated CoW from previous - * depsgraph, so we don't need to re-tag anything what we already have. - */ - id_node->tag_update(graph); +#ifdef WITH_COPY_ON_WRITE + DEG_id_tag_update_ex(graph->bmain, id_node->id_orig, DEG_TAG_COPY_ON_WRITE); +#endif } GHASH_FOREACH_END(); } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 935b8c543ec..81bb8454976 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -144,6 +144,12 @@ void constraint_walk(bConstraint * /*con*/, } } +void free_copy_on_write_datablock(void *id_v) +{ + ID *id = (ID *)id_v; + deg_free_copy_on_write_datablock(id); +} + } /* namespace */ /* ************ */ @@ -153,18 +159,30 @@ void constraint_walk(bConstraint * /*con*/, DepsgraphNodeBuilder::DepsgraphNodeBuilder(Main *bmain, Depsgraph *graph) : m_bmain(bmain), - m_graph(graph) + m_graph(graph), + m_cow_id_hash(NULL) { } DepsgraphNodeBuilder::~DepsgraphNodeBuilder() { + if (m_cow_id_hash != NULL) { + BLI_ghash_free(m_cow_id_hash, NULL, free_copy_on_write_datablock); + } } -IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id) +IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id, bool do_tag) { - IDDepsNode *id_node = m_graph->add_id_node(id, id->name); #ifdef WITH_COPY_ON_WRITE + IDDepsNode *id_node = NULL; + ID *id_cow = (ID *)BLI_ghash_lookup(m_cow_id_hash, id); + if (id_cow != NULL) { + /* TODO(sergey): Is it possible to lookup and pop element from GHash + * at the same time? + */ + BLI_ghash_remove(m_cow_id_hash, id, NULL, NULL); + } + id_node = m_graph->add_id_node(id, do_tag, id_cow); /* Currently all ID nodes are supposed to have copy-on-write logic. * * NOTE: Zero number of components indicates that ID node was just created. @@ -178,6 +196,8 @@ IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id) "", -1); m_graph->operations.push_back(op_cow); } +#else + IDDepsNode *id_node = m_graph->add_id_node(id); #endif return id_node; } @@ -295,6 +315,27 @@ ID *DepsgraphNodeBuilder::get_cow_id(const ID *id_orig) const return m_graph->get_cow_id(id_orig); } +ID *DepsgraphNodeBuilder::ensure_cow_id(ID *id_orig) +{ + if (id_orig->tag & LIB_TAG_COPY_ON_WRITE) { + /* ID is already remapped to copy-on-write. */ + return id_orig; + } + IDDepsNode *id_node = add_id_node(id_orig, false); + return id_node->id_cow; +} + +ID *DepsgraphNodeBuilder::expand_cow_id(IDDepsNode *id_node) +{ + return deg_expand_copy_on_write_datablock(m_graph, id_node, this, true); +} + +ID *DepsgraphNodeBuilder::expand_cow_id(ID *id_orig) +{ + IDDepsNode *id_node = add_id_node(id_orig); + return expand_cow_id(id_node); +} + /* **** Build functions for entity nodes **** */ void DepsgraphNodeBuilder::begin_build(Main *bmain) { @@ -307,11 +348,36 @@ void DepsgraphNodeBuilder::begin_build(Main *bmain) { /* XXX nested node trees are not included in tag-clearing above, * so we need to do this manually. */ - FOREACH_NODETREE(bmain, nodetree, id) { + FOREACH_NODETREE(bmain, nodetree, id) + { if (id != (ID *)nodetree) { nodetree->id.tag &= ~LIB_TAG_DOIT; } - } FOREACH_NODETREE_END + } + FOREACH_NODETREE_END; + +#ifdef WITH_COPY_ON_WRITE + /* Store existing copy-on-write versions of datablock, so we can re-use + * them for new ID nodes. + */ + m_cow_id_hash = BLI_ghash_ptr_new("Depsgraph id hash"); + GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, m_graph->id_hash) + { + if (GS(id_node->id_orig->name) != ID_SCE) { + continue; + } + if (deg_copy_on_write_is_expanded(id_node->id_cow)) { + BLI_ghash_insert(m_cow_id_hash, id_node->id_orig, id_node->id_cow); + id_node->id_cow = NULL; + } + } + GHASH_FOREACH_END(); +#endif + + /* Make sure graph has no nodes left from previous state. */ + m_graph->clear_all_nodes(); + m_graph->operations.clear(); + BLI_gset_clear(m_graph->entry_tags, NULL); } void DepsgraphNodeBuilder::build_group(Scene *scene, Group *group) @@ -475,7 +541,7 @@ void DepsgraphNodeBuilder::build_object_transform(Scene *scene, Object *ob) function_bind(BKE_object_eval_uber_transform, _1, scene_cow, ob_cow), - DEG_OPCODE_OBJECT_UBEREVAL); + DEG_OPCODE_TRANSFORM_OBJECT_UBEREVAL); /* object transform is done */ op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM, @@ -521,10 +587,12 @@ void DepsgraphNodeBuilder::build_animdata(ID *id) if (adt == NULL) { return; } - ID *id_cow = get_cow_id(id); /* animation */ if (adt->action || adt->nla_tracks.first || adt->drivers.first) { + (void) add_id_node(id); + ID *id_cow = get_cow_id(id); + // XXX: Hook up specific update callbacks for special properties which // may need it... @@ -558,7 +626,6 @@ void DepsgraphNodeBuilder::build_animdata(ID *id) */ OperationDepsNode *DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcu) { - ChannelDriver *driver = fcu->driver; ID *id_cow = get_cow_id(id); /* Create data node for this driver */ @@ -582,11 +649,6 @@ OperationDepsNode *DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcu) fcu->array_index); } - /* tag "scripted expression" drivers as needing Python (due to GIL issues, etc.) */ - if (driver->type == DRIVER_TYPE_PYTHON) { - driver_op->flag |= DEPSOP_FLAG_USES_PYTHON; - } - /* return driver node created */ return driver_op; } @@ -602,10 +664,10 @@ void DepsgraphNodeBuilder::build_world(World *world) build_animdata(world_id); /* world itself */ - add_component_node(world_id, DEG_NODE_TYPE_PARAMETERS); - - add_operation_node(world_id, DEG_NODE_TYPE_PARAMETERS, NULL, - DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); + add_operation_node(world_id, + DEG_NODE_TYPE_SHADING, + function_bind(BKE_world_eval, _1, world), + DEG_OPCODE_WORLD_UPDATE); /* textures */ build_texture_stack(world->mtex); @@ -679,7 +741,7 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene) _1, scene_cow, get_cow_datablock(ob)), - DEG_OPCODE_TRANSFORM_RIGIDBODY); + DEG_OPCODE_RIGIDBODY_TRANSFORM_COPY); } } } @@ -709,28 +771,60 @@ void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob) Scene *scene_cow = get_cow_datablock(scene); Object *ob_cow = get_cow_datablock(ob); + add_operation_node(psys_comp, + function_bind(BKE_particle_system_eval_init, + _1, + scene_cow, + ob_cow), + DEG_OPCODE_PARTICLE_SYSTEM_EVAL_INIT); + /* particle systems */ LINKLIST_FOREACH (ParticleSystem *, psys, &ob->particlesystem) { ParticleSettings *part = psys->part; - /* particle settings */ - // XXX: what if this is used more than once! - build_animdata(&part->id); + /* Build particle settings operations. + * + * NOTE: The call itself ensures settings are only build once. + */ + build_particle_settings(part); - /* this particle system */ - // TODO: for now, this will just be a placeholder "ubereval" node + /* Update on particle settings change. */ add_operation_node(psys_comp, - function_bind(BKE_particle_system_eval, + function_bind(BKE_particle_system_settings_eval, _1, - scene_cow, - ob_cow, psys), - DEG_OPCODE_PSYS_EVAL, + DEG_OPCODE_PARTICLE_SETTINGS_EVAL, + psys->name); + + /* Particle system evaluation. */ + add_operation_node(psys_comp, + NULL, + DEG_OPCODE_PARTICLE_SYSTEM_EVAL, psys->name); } - /* pointcache */ - // TODO... + /* TODO(sergey): Do we need a point cache operations here? */ +} + +void DepsgraphNodeBuilder::build_particle_settings(ParticleSettings *part) { + ID *part_id = &part->id; + if (part_id->tag & LIB_TAG_DOIT) { + return; + } + part_id->tag |= LIB_TAG_DOIT; + /* Animation data. */ + build_animdata(part_id); + /* Parameters change. */ + add_operation_node(part_id, + DEG_NODE_TYPE_PARAMETERS, + NULL, + DEG_OPCODE_PARTICLE_SETTINGS_EVAL); + add_operation_node(part_id, + DEG_NODE_TYPE_PARAMETERS, + function_bind(BKE_particle_system_settings_recalc_clear, + _1, + part), + DEG_OPCODE_PARTICLE_SETTINGS_RECALC_CLEAR); } void DepsgraphNodeBuilder::build_cloth(Scene *scene, Object *object) @@ -762,8 +856,6 @@ void DepsgraphNodeBuilder::build_shapekeys(Key *key) // XXX: what happens if the datablock is shared! void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) { - ID *obdata = (ID *)ob->data; - ID *obdata_cow = get_cow_id(obdata); OperationDepsNode *op_node; Scene *scene_cow = get_cow_datablock(scene); Object *object_cow = get_cow_datablock(ob); @@ -776,8 +868,7 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_PARAMETERS, NULL, - DEG_OPCODE_PLACEHOLDER, - "Parameters Eval"); + DEG_OPCODE_PARAMETERS_EVAL); op_node->set_as_exit(); /* Temporary uber-update node, which does everything. @@ -835,9 +926,14 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) // add geometry collider relations } + ID *obdata = (ID *)ob->data; if (obdata->tag & LIB_TAG_DOIT) { return; } + obdata->tag |= LIB_TAG_DOIT; + /* Make sure we've got an ID node before requesting CoW pointer. */ + (void) add_id_node((ID *)obdata); + ID *obdata_cow = get_cow_id(obdata); /* ShapeKeys */ Key *key = BKE_key_from_object(ob); @@ -949,8 +1045,10 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) op_node->set_as_exit(); /* Parameters for driver sources. */ - add_operation_node(obdata, DEG_NODE_TYPE_PARAMETERS, NULL, - DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); + add_operation_node(obdata, + DEG_NODE_TYPE_PARAMETERS, + NULL, + DEG_OPCODE_PARAMETERS_EVAL); } /* Cameras */ @@ -965,8 +1063,10 @@ void DepsgraphNodeBuilder::build_camera(Object *ob) build_animdata(&cam->id); - add_operation_node(camera_id, DEG_NODE_TYPE_PARAMETERS, NULL, - DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); + add_operation_node(camera_id, + DEG_NODE_TYPE_PARAMETERS, + NULL, + DEG_OPCODE_PARAMETERS_EVAL); if (cam->dof_ob != NULL) { /* TODO(sergey): For now parametrs are on object level. */ @@ -990,8 +1090,10 @@ void DepsgraphNodeBuilder::build_lamp(Object *ob) add_component_node(lamp_id, DEG_NODE_TYPE_PARAMETERS); /* TODO(sergey): Is it really how we're supposed to work with drivers? */ - add_operation_node(lamp_id, DEG_NODE_TYPE_PARAMETERS, NULL, - DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); + add_operation_node(lamp_id, + DEG_NODE_TYPE_PARAMETERS, + NULL, + DEG_OPCODE_PARAMETERS_EVAL); /* lamp's nodetree */ if (la->nodetree) { @@ -1014,10 +1116,18 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) build_animdata(ntree_id); /* Parameters for drivers. */ - op_node = add_operation_node(ntree_id, DEG_NODE_TYPE_PARAMETERS, NULL, - DEG_OPCODE_PLACEHOLDER, "Parameters Eval"); + op_node = add_operation_node(ntree_id, + DEG_NODE_TYPE_PARAMETERS, + NULL, + DEG_OPCODE_PARAMETERS_EVAL); op_node->set_as_exit(); + /* Shading update. */ + add_operation_node(ntree_id, + DEG_NODE_TYPE_SHADING, + NULL, + DEG_OPCODE_MATERIAL_UPDATE); + /* nodetree's nodes... */ LINKLIST_FOREACH (bNode *, bnode, &ntree->nodes) { ID *id = bnode->id; @@ -1055,8 +1165,11 @@ void DepsgraphNodeBuilder::build_material(Material *ma) /* material itself */ add_id_node(ma_id); - add_operation_node(ma_id, DEG_NODE_TYPE_SHADING, NULL, - DEG_OPCODE_PLACEHOLDER, "Material Update"); + /* Shading update. */ + add_operation_node(ma_id, + DEG_NODE_TYPE_SHADING, + function_bind(BKE_material_eval, _1, ma), + DEG_OPCODE_MATERIAL_UPDATE); /* material animation */ build_animdata(ma_id); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 81fbbb07bc8..7e28df1276d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -49,6 +49,7 @@ struct MTex; struct MovieClip; struct bNodeTree; struct Object; +struct ParticleSettings; struct Probe; struct bPoseChannel; struct bConstraint; @@ -71,16 +72,42 @@ struct DepsgraphNodeBuilder { DepsgraphNodeBuilder(Main *bmain, Depsgraph *graph); ~DepsgraphNodeBuilder(); - void begin_build(Main *bmain); - + /* For given original ID get ID which is created by CoW system. */ ID *get_cow_id(const ID *id_orig) const; + /* Similar to above, but for the cases when there is no ID node we create + * one. + */ + ID *ensure_cow_id(ID *id_orig); + /* Helper wrapper function which wraps get_cow_id with a needed type cast. */ template<typename T> T *get_cow_datablock(const T *orig) const { return (T *)get_cow_id(&orig->id); } - IDDepsNode *add_id_node(ID *id); + /* Get fully expanded (ready for use) copy-on-write datablock for the given + * original datablock. + */ + ID *expand_cow_id(IDDepsNode *id_node); + ID *expand_cow_id(ID *id_orig); + template<typename T> + T *expand_cow_datablock(T *orig) { + return (T *)expand_cow_id(&orig->id); + } + + /* For a given COW datablock get corresponding original one. */ + template<typename T> + T *get_orig_datablock(const T *cow) const { +#ifdef WITH_COPY_ON_WRITE + return (T *)cow->id.newid; +#else + return (T *)cow; +#endif + } + + void begin_build(Main *bmain); + + IDDepsNode *add_id_node(ID *id, bool do_tag = true); TimeSourceDepsNode *add_time_source(); ComponentDepsNode *add_component_node(ID *id, @@ -134,6 +161,7 @@ struct DepsgraphNodeBuilder { void build_pose_constraints(Scene *scene, Object *ob, bPoseChannel *pchan); void build_rigidbody(Scene *scene); void build_particles(Scene *scene, Object *ob); + void build_particle_settings(ParticleSettings *part); void build_cloth(Scene *scene, Object *object); void build_animdata(ID *id); OperationDepsNode *build_driver(ID *id, FCurve *fcurve); @@ -178,6 +206,7 @@ struct DepsgraphNodeBuilder { protected: Main *m_bmain; Depsgraph *m_graph; + GHash *m_cow_id_hash; }; } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc index b6df176545e..3ce0947a7b8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc @@ -98,9 +98,7 @@ void DepsgraphNodeBuilder::build_scene_layer_collections(Scene *scene) { #ifdef WITH_COPY_ON_WRITE /* Make sure we've got ID node, so we can get pointer to CoW datablock. */ - IDDepsNode *id_node = add_id_node(&scene->id); - Scene *scene_cow = (Scene *)deg_expand_copy_on_write_datablock(m_graph, - id_node); + Scene *scene_cow = expand_cow_datablock(scene); #else Scene *scene_cow = scene; #endif diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc index 69f02603f40..f283377d7bb 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc @@ -134,18 +134,14 @@ void DepsgraphNodeBuilder::build_splineik_pose(Scene *scene, void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *object) { bArmature *armature = (bArmature *)object->data; - const bool armature_tag = armature->id.tag; + const short armature_tag = armature->id.tag; #ifdef WITH_COPY_ON_WRITE /* NOTE: We need to expand both object and armature, so this way we can * safely create object level pose. */ Scene *scene_cow = get_cow_datablock(scene); - IDDepsNode *object_id_node = add_id_node(&object->id); - Object *object_cow = (Object *)deg_expand_copy_on_write_datablock( - m_graph, object_id_node); - IDDepsNode *armature_id_node = add_id_node(&armature->id); - bArmature *armature_cow = (bArmature *)deg_expand_copy_on_write_datablock( - m_graph, armature_id_node); + Object *object_cow = expand_cow_datablock(object); + bArmature *armature_cow = expand_cow_datablock(armature); #else Scene *scene_cow = scene; Object *object_cow = object; @@ -259,14 +255,12 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *object) function_bind(BKE_pose_bone_done, _1, pchan), DEG_OPCODE_BONE_DONE); op_node->set_as_exit(); - - /* constraints */ + /* Build constraints. */ if (pchan->constraints.first != NULL) { build_pose_constraints(scene, object, pchan); } - /** - * IK Solvers... + * IK Solvers. * * - These require separate processing steps are pose-level * to be executed between chains of bones (i.e. once the @@ -291,6 +285,11 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *object) break; } } + /* Custom shape. */ + /* NOTE: Custom shape datablock is already remapped to CoW version. */ + if (pchan->custom != NULL) { + build_object(scene, get_orig_datablock(pchan->custom)); + } } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc index f24d4e8d3f2..a8acc88f7f3 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc @@ -89,6 +89,9 @@ void DepsgraphNodeBuilder::build_scene(Main *bmain, Scene *scene) base->object->select_color = select_color++; } } + if (scene->camera != NULL) { + build_object(scene, scene->camera); + } /* rigidbody */ if (scene->rigidbody_world) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 2665f28ee94..861aa9521c0 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -324,7 +324,7 @@ void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name) { - ListBase *effectors = pdInitEffectors(scene, ob, psys, eff, false); + ListBase *effectors = pdInitEffectors(NULL, scene, ob, psys, eff, false); if (effectors) { for (EffectorCache *eff = (EffectorCache *)effectors->first; eff; eff = eff->next) { @@ -343,7 +343,7 @@ void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key, add_relation(mod_key, key, name); } else if (eff->psys != psys) { - OperationKey eff_key(&eff->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, eff->psys->name); + OperationKey eff_key(&eff->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PARTICLE_SYSTEM_EVAL, eff->psys->name); add_relation(eff_key, key, name); } } @@ -423,7 +423,7 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o OperationKey parent_transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_PARENT); OperationKey final_transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL); - OperationKey ob_ubereval_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_OBJECT_UBEREVAL); + OperationKey ob_ubereval_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_OBJECT_UBEREVAL); /* parenting */ if (ob->parent != NULL) { @@ -521,7 +521,7 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o build_proxy_rig(ob); } else { - build_rig(scene, ob); + build_rig(bmain, scene, ob); } break; @@ -929,8 +929,8 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) fcu->rna_path ? fcu->rna_path : "", fcu->array_index); bPoseChannel *pchan = NULL; - const char *rna_path = fcu->rna_path ? fcu->rna_path : ""; + const short id_type = GS(id->name); /* create dependency between driver and data affected by it */ /* - direct property relationship... */ @@ -943,18 +943,17 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) /* interleaved drivers during bone eval */ // TODO: ideally, if this is for a constraint, it goes to said constraint Object *ob = (Object *)id; - char *bone_name; - - bone_name = BLI_str_quoted_substrN(rna_path, "pose.bones["); + char *bone_name = BLI_str_quoted_substrN(rna_path, "pose.bones["); pchan = BKE_pose_channel_find_name(ob->pose, bone_name); - - if (bone_name) { + if (bone_name != NULL) { MEM_freeN(bone_name); bone_name = NULL; } - - if (pchan) { - OperationKey bone_key(id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL); + if (pchan != NULL) { + OperationKey bone_key(id, + DEG_NODE_TYPE_BONE, + pchan->name, + DEG_OPCODE_BONE_LOCAL); add_relation(driver_key, bone_key, "[Driver -> Bone]"); } else { @@ -963,31 +962,36 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) rna_path); } } - else if (GS(id->name) == ID_AR && strstr(rna_path, "bones[")) { - /* drivers on armature-level bone settings (i.e. bbone stuff), - * which will affect the evaluation of corresponding pose bones + else if (id_type == ID_AR && strstr(rna_path, "bones[")) { + /* Drivers on armature-level bone settings (i.e. bbone stuff), + * which will affect the evaluation of corresponding pose bones. */ IDDepsNode *arm_node = m_graph->find_id_node(id); char *bone_name = BLI_str_quoted_substrN(rna_path, "bones["); - - if (arm_node && bone_name) { - /* find objects which use this, and make their eval callbacks depend on this */ + if (arm_node != NULL && bone_name != NULL) { + /* Find objects which use this, and make their eval callbacks + * depend on this. + */ foreach (DepsRelation *rel, arm_node->outlinks) { IDDepsNode *to_node = (IDDepsNode *)rel->to; - - /* we only care about objects with pose data which use this... */ + /* We only care about objects with pose data which use this. */ if (GS(to_node->id_orig->name) == ID_OB) { Object *ob = (Object *)to_node->id_orig; - bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name); // NOTE: ob->pose may be NULL - - if (pchan) { - OperationKey bone_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL); - add_relation(driver_key, bone_key, "[Arm Bone -> Driver -> Bone]"); + // NOTE: ob->pose may be NULL + bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, + bone_name); + if (pchan != NULL) { + OperationKey bone_key(&ob->id, + DEG_NODE_TYPE_BONE, + pchan->name, + DEG_OPCODE_BONE_LOCAL); + add_relation(driver_key, + bone_key, + "[Arm Bone -> Driver -> Bone]"); } } } - - /* free temp data */ + /* Free temp data/ */ MEM_freeN(bone_name); bone_name = NULL; } @@ -997,8 +1001,10 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) rna_path); } } - else if (GS(id->name) == ID_OB && strstr(rna_path, "modifiers[")) { - OperationKey modifier_key(id, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL); + else if (id_type == ID_OB && strstr(rna_path, "modifiers[")) { + OperationKey modifier_key(id, + DEG_NODE_TYPE_GEOMETRY, + DEG_OPCODE_GEOMETRY_UBEREVAL); if (has_node(modifier_key)) { add_relation(driver_key, modifier_key, "[Driver -> Modifier]"); } @@ -1006,11 +1012,10 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) printf("Unexisting driver RNA path: %s\n", rna_path); } } - else if (GS(id->name) == ID_KE && strstr(rna_path, "key_blocks[")) { - /* shape key driver - hook into the base geometry operation */ + else if (id_type == ID_KE && strstr(rna_path, "key_blocks[")) { + /* Shape key driver - hook into the base geometry operation. */ // XXX: double check where this points Key *shape_key = (Key *)id; - ComponentKey geometry_key(shape_key->from, DEG_NODE_TYPE_GEOMETRY); add_relation(driver_key, geometry_key, "[Driver -> ShapeKey Geom]"); } @@ -1019,14 +1024,36 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) add_relation(driver_key, geometry_key, "[Driver -> ShapeKey Geom]"); } else { - if (GS(id->name) == ID_OB) { - /* assume that driver affects a transform... */ - OperationKey local_transform_key(id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL); - add_relation(driver_key, local_transform_key, "[Driver -> Transform]"); - } - else if (GS(id->name) == ID_KE) { - ComponentKey geometry_key(id, DEG_NODE_TYPE_GEOMETRY); - add_relation(driver_key, geometry_key, "[Driver -> Shapekey Geometry]"); + switch (id_type) { + case ID_OB: + { + /* Assume that driver affects a transform. */ + OperationKey local_transform_key(id, + DEG_NODE_TYPE_TRANSFORM, + DEG_OPCODE_TRANSFORM_LOCAL); + add_relation(driver_key, + local_transform_key, + "[Driver -> Transform]"); + break; + } + case ID_KE: + { + ComponentKey geometry_key(id, DEG_NODE_TYPE_GEOMETRY); + add_relation(driver_key, + geometry_key, + "[Driver -> Shapekey Geometry]"); + break; + } + case ID_NT: + { + OperationKey ntree_key(id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PARAMETERS_EVAL); + add_relation(driver_key, + ntree_key, + "[Driver -> NTree Shading Update]"); + break; + } } } @@ -1135,9 +1162,9 @@ void DepsgraphRelationBuilder::build_world(World *world) /* world's nodetree */ if (world->nodetree != NULL) { build_nodetree(world->nodetree); - ComponentKey ntree_key(&world->nodetree->id, DEG_NODE_TYPE_PARAMETERS); - ComponentKey world_key(world_id, DEG_NODE_TYPE_PARAMETERS); - add_relation(ntree_key, world_key, "NTree->World Parameters"); + ComponentKey ntree_key(&world->nodetree->id, DEG_NODE_TYPE_SHADING); + ComponentKey world_key(world_id, DEG_NODE_TYPE_SHADING); + add_relation(ntree_key, world_key, "NTree->World Shading Update"); } } @@ -1173,7 +1200,7 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) * XXX: there's probably a difference between passive and active * - passive don't change, so may need to know full transform... */ - OperationKey rbo_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY); + OperationKey rbo_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_RIGIDBODY_TRANSFORM_COPY); eDepsOperation_Code trans_opcode = ob->parent ? DEG_OPCODE_TRANSFORM_PARENT : DEG_OPCODE_TRANSFORM_LOCAL; OperationKey trans_op(&ob->id, DEG_NODE_TYPE_TRANSFORM, trans_opcode); @@ -1202,7 +1229,7 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) */ OperationKey uber_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, - DEG_OPCODE_OBJECT_UBEREVAL); + DEG_OPCODE_TRANSFORM_OBJECT_UBEREVAL); add_relation(rbo_key, uber_key, "RBO Sync -> Uber (Temp)"); } @@ -1225,8 +1252,8 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) * constraint affects the physics sim for these objects */ ComponentKey trans_key(&ob->id, DEG_NODE_TYPE_TRANSFORM); - OperationKey ob1_key(&rbc->ob1->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY); - OperationKey ob2_key(&rbc->ob2->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY); + OperationKey ob1_key(&rbc->ob1->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_RIGIDBODY_TRANSFORM_COPY); + OperationKey ob2_key(&rbc->ob2->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_RIGIDBODY_TRANSFORM_COPY); /* - constrained-objects sync depends on the constraint-holder */ add_relation(trans_key, ob1_key, "RigidBodyConstraint -> RBC.Object_1"); @@ -1244,25 +1271,53 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) OperationKey obdata_ubereval_key(&ob->id, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL); + OperationKey eval_init_key(&ob->id, + DEG_NODE_TYPE_EVAL_PARTICLES, + DEG_OPCODE_PARTICLE_SYSTEM_EVAL_INIT); + /* TODO(sergey): Are all particle systems depends on time? + * Hair without dynamics i.e. + */ + add_relation(time_src_key, eval_init_key, "TimeSrc -> PSys"); /* particle systems */ LINKLIST_FOREACH (ParticleSystem *, psys, &ob->particlesystem) { ParticleSettings *part = psys->part; - /* particle settings */ - build_animdata(&part->id); - - /* this particle system */ - OperationKey psys_key(&ob->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, psys->name); + /* Build particle settings relations. + * + * NOTE: The call itself ensures settings are only build once. + */ + build_particle_settings(part); + + /* This particle system. */ + OperationKey psys_key(&ob->id, + DEG_NODE_TYPE_EVAL_PARTICLES, + DEG_OPCODE_PARTICLE_SYSTEM_EVAL, + psys->name); + + /* Update particle system when settings changes. */ + OperationKey particle_settings_key(&part->id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PARTICLE_SETTINGS_EVAL); + OperationKey particle_settings_recalc_clear_key( + &part->id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PARTICLE_SETTINGS_RECALC_CLEAR); + OperationKey psys_settings_key(&ob->id, + DEG_NODE_TYPE_EVAL_PARTICLES, + DEG_OPCODE_PARTICLE_SETTINGS_EVAL, + psys->name); + add_relation(particle_settings_key, psys_settings_key, "Particle Settings Change"); + add_relation(psys_settings_key, psys_key, "Particle Settings Update"); + add_relation(psys_key, + particle_settings_recalc_clear_key, + "Particle Settings Recalc Clear"); /* XXX: if particle system is later re-enabled, we must do full rebuild? */ if (!psys_check_enabled(ob, psys, G.is_rendering)) continue; - /* TODO(sergey): Are all particle systems depends on time? - * Hair without dynamics i.e. - */ - add_relation(time_src_key, psys_key, "TimeSrc -> PSys"); + add_relation(eval_init_key, psys_key, "Init -> PSys"); /* TODO(sergey): Currently particle update is just a placeholder, * hook it to the ubereval node so particle system is getting updated @@ -1272,14 +1327,32 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) /* collisions */ if (part->type != PART_HAIR) { - add_collision_relations(psys_key, scene, ob, part->collision_group, true, "Particle Collision"); + add_collision_relations(psys_key, + scene, + ob, + part->collision_group, + true, + "Particle Collision"); } - else if ((psys->flag & PSYS_HAIR_DYNAMICS) && psys->clmd && psys->clmd->coll_parms) { - add_collision_relations(psys_key, scene, ob, psys->clmd->coll_parms->group, true, "Hair Collision"); + else if ((psys->flag & PSYS_HAIR_DYNAMICS) && + psys->clmd != NULL && + psys->clmd->coll_parms != NULL) { + add_collision_relations(psys_key, + scene, + ob, + psys->clmd->coll_parms->group, + true, + "Hair Collision"); } /* effectors */ - add_forcefield_relations(psys_key, scene, ob, psys, part->effector_weights, part->type == PART_HAIR, "Particle Field"); + add_forcefield_relations(psys_key, + scene, + ob, + psys, + part->effector_weights, + part->type == PART_HAIR, + "Particle Field"); /* boids */ if (part->boids) { @@ -1314,8 +1387,27 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) ComponentKey transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM); add_relation(transform_key, obdata_ubereval_key, "Partcile Eval"); - /* pointcache */ - // TODO... + /* TODO(sergey): Do we need a point cache operations here? */ +} + +void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part) +{ + ID *part_id = &part->id; + if (part_id->tag & LIB_TAG_DOIT) { + return; + } + part_id->tag |= LIB_TAG_DOIT; + + /* Animation data relations. */ + build_animdata(&part->id); + + OperationKey eval_key(part_id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PARTICLE_SETTINGS_EVAL); + OperationKey recalc_clear_key(part_id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_PARTICLE_SETTINGS_RECALC_CLEAR); + add_relation(eval_key, recalc_clear_key, "Particle Settings Clear Recalc"); } void DepsgraphRelationBuilder::build_cloth(Scene * /*scene*/, @@ -1452,8 +1544,7 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje if (ob->type == OB_MESH) { OperationKey material_key(&ma->id, DEG_NODE_TYPE_SHADING, - DEG_OPCODE_PLACEHOLDER, - "Material Update"); + DEG_OPCODE_MATERIAL_UPDATE); OperationKey shading_key(&ob->id, DEG_NODE_TYPE_SHADING, DEG_OPCODE_SHADING); add_relation(material_key, shading_key, "Material Update"); } @@ -1626,6 +1717,21 @@ void DepsgraphRelationBuilder::build_lamp(Object *ob) /* textures */ build_texture_stack(la->mtex); + +#ifdef WITH_COPY_ON_WRITE + /* Make sure copy on write of lamp data is always properly updated for + * visible lamps. + */ + OperationKey ob_copy_on_write_key(&ob->id, + DEG_NODE_TYPE_COPY_ON_WRITE, + DEG_OPCODE_COPY_ON_WRITE); + OperationKey lamp_copy_on_write_key(lamp_id, + DEG_NODE_TYPE_COPY_ON_WRITE, + DEG_OPCODE_COPY_ON_WRITE); + add_relation(lamp_copy_on_write_key, + ob_copy_on_write_key, + "Evaluation Order"); +#endif } void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) @@ -1639,8 +1745,7 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) OperationKey parameters_key(ntree_id, DEG_NODE_TYPE_PARAMETERS, - DEG_OPCODE_PLACEHOLDER, - "Parameters Eval"); + DEG_OPCODE_PARAMETERS_EVAL); /* nodetree's nodes... */ LINKLIST_FOREACH (bNode *, bnode, &ntree->nodes) { @@ -1659,8 +1764,7 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) } OperationKey group_parameters_key(&group_ntree->id, DEG_NODE_TYPE_PARAMETERS, - DEG_OPCODE_PLACEHOLDER, - "Parameters Eval"); + DEG_OPCODE_PARAMETERS_EVAL); add_relation(group_parameters_key, parameters_key, "Group Node"); } } @@ -1670,6 +1774,11 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) ComponentKey animation_key(ntree_id, DEG_NODE_TYPE_ANIMATION); add_relation(animation_key, parameters_key, "NTree Parameters"); } + + OperationKey shading_update_key(ntree_id, + DEG_NODE_TYPE_SHADING, + DEG_OPCODE_MATERIAL_UPDATE); + add_relation(parameters_key, shading_update_key, "NTree Parameters"); } /* Recursively build graph for material */ @@ -1691,13 +1800,11 @@ void DepsgraphRelationBuilder::build_material(Material *ma) if (ma->nodetree != NULL) { build_nodetree(ma->nodetree); OperationKey ntree_key(&ma->nodetree->id, - DEG_NODE_TYPE_PARAMETERS, - DEG_OPCODE_PLACEHOLDER, - "Parameters Eval"); + DEG_NODE_TYPE_SHADING, + DEG_OPCODE_MATERIAL_UPDATE); OperationKey material_key(&ma->id, DEG_NODE_TYPE_SHADING, - DEG_OPCODE_PLACEHOLDER, - "Material Update"); + DEG_OPCODE_MATERIAL_UPDATE); add_relation(ntree_key, material_key, "Material's NTree"); } } @@ -1810,7 +1917,7 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDDepsNode *id_node DEG_NODE_TYPE_COPY_ON_WRITE, DEG_OPCODE_COPY_ON_WRITE); /* XXX: This is a quick hack to make Alt-A to work. */ - add_relation(time_source_key, copy_on_write_key, "Fluxgate capacitor hack"); + // add_relation(time_source_key, copy_on_write_key, "Fluxgate capacitor hack"); /* Resat of code is using rather low level trickery, so need to get some * explicit pointers. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 8a53bf4a6bf..e8bdc662bd6 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -70,6 +70,7 @@ struct Tex; struct World; struct EffectorWeights; struct ParticleSystem; +struct ParticleSettings; struct PropertyRNA; @@ -199,6 +200,7 @@ struct DepsgraphRelationBuilder void build_world(World *world); void build_rigidbody(Scene *scene); void build_particles(Scene *scene, Object *ob); + void build_particle_settings(ParticleSettings *part); void build_cloth(Scene *scene, Object *object, ModifierData *md); void build_ik_pose(Object *ob, bPoseChannel *pchan, @@ -208,7 +210,7 @@ struct DepsgraphRelationBuilder bPoseChannel *pchan, bConstraint *con, RootPChanMap *root_map); - void build_rig(Scene *scene, Object *ob); + void build_rig(Main *bmain, Scene *scene, Object *ob); void build_proxy_rig(Object *ob); void build_shapekeys(ID *obdata, Key *key); void build_obdata_geom(Main *bmain, Scene *scene, Object *ob); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc index be666165a0b..2c2aa5d6651 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -291,7 +291,7 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *ob, } /* Pose/Armature Bones Graph */ -void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob) +void DepsgraphRelationBuilder::build_rig(Main *bmain, Scene *scene, Object *ob) { /* Armature-Data */ bArmature *arm = (bArmature *)ob->data; @@ -379,16 +379,12 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob) OperationKey bone_pose_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_POSE_PARENT); OperationKey bone_ready_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY); OperationKey bone_done_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE); - pchan->flag &= ~POSE_DONE; - - /* pose init to bone local */ + /* Pose init to bone local. */ add_relation(init_key, bone_local_key, "PoseEval Source-Bone Link"); - - /* local to pose parenting operation */ + /* Local to pose parenting operation. */ add_relation(bone_local_key, bone_pose_key, "Bone Local - PoseSpace Link"); - - /* parent relation */ + /* Parent relation. */ if (pchan->parent != NULL) { eDepsOperation_Code parent_key_opcode; @@ -403,8 +399,7 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob) OperationKey parent_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->parent->name, parent_key_opcode); add_relation(parent_key, bone_pose_key, "[Parent Bone -> Child Bone]"); } - - /* constraints */ + /* Buil constraints. */ if (pchan->constraints.first != NULL) { /* constraints stack and constraint dependencies */ build_constraints(scene, &ob->id, DEG_NODE_TYPE_BONE, pchan->name, &pchan->constraints, &root_map); @@ -431,6 +426,10 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob) /* assume that all bones must be done for the pose to be ready (for deformers) */ add_relation(bone_done_key, flush_key, "PoseEval Result-Bone Link"); + /* Custom shape. */ + if (pchan->custom != NULL) { + build_object(bmain, scene, pchan->custom); + } } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc index 4b8d5119cf6..deed46339bb 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc @@ -84,6 +84,9 @@ void DepsgraphRelationBuilder::build_scene(Main *bmain, Scene *scene) build_object(bmain, scene, base->object); } } + if (scene->camera != NULL) { + build_object(bmain, scene, scene->camera); + } /* rigidbody */ if (scene->rigidbody_world) { diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index dc3174751bd..9664d389794 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -53,6 +53,8 @@ extern "C" { #include "DEG_depsgraph.h" +#include "intern/eval/deg_eval_copy_on_write.h" + #include "intern/nodes/deg_node.h" #include "intern/nodes/deg_node_component.h" #include "intern/nodes/deg_node_operation.h" @@ -250,11 +252,13 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr, /* Node Management ---------------------------- */ +#ifndef WITH_COPY_ON_WRITE static void id_node_deleter(void *value) { IDDepsNode *id_node = reinterpret_cast<IDDepsNode *>(value); OBJECT_GUARDED_DELETE(id_node, IDDepsNode); } +#endif TimeSourceDepsNode *Depsgraph::add_time_source() { @@ -275,26 +279,58 @@ IDDepsNode *Depsgraph::find_id_node(const ID *id) const return reinterpret_cast<IDDepsNode *>(BLI_ghash_lookup(id_hash, id)); } -IDDepsNode *Depsgraph::add_id_node(ID *id, const char *name) +IDDepsNode *Depsgraph::add_id_node(ID *id, bool do_tag, ID *id_cow_hint) { + BLI_assert((id->tag & LIB_TAG_COPY_ON_WRITE) == 0); IDDepsNode *id_node = find_id_node(id); if (!id_node) { DepsNodeFactory *factory = deg_get_node_factory(DEG_NODE_TYPE_ID_REF); - id_node = (IDDepsNode *)factory->create_node(id, "", name); - id->tag |= LIB_TAG_DOIT; + id_node = (IDDepsNode *)factory->create_node(id, "", id->name); + id_node->init_copy_on_write(id_cow_hint); + if (do_tag) { + id->tag |= LIB_TAG_DOIT; + } /* Register node in ID hash. * * NOTE: We address ID nodes by the original ID pointer they are * referencing to. */ BLI_ghash_insert(id_hash, id, id_node); + } else if (do_tag) { + id->tag |= LIB_TAG_DOIT; } return id_node; } void Depsgraph::clear_id_nodes() { +#ifndef WITH_COPY_ON_WRITE BLI_ghash_clear(id_hash, NULL, id_node_deleter); +#else + /* Stupid workaround to ensure we free IDs in a proper order. */ + GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, id_hash) + { + if (id_node->id_cow == NULL) { + /* This means builder "stole" ownership of the copy-on-written + * datablock for her own dirty needs. + */ + continue; + } + if (!deg_copy_on_write_is_expanded(id_node->id_cow)) { + continue; + } + const short id_type = GS(id_node->id_cow->name); + if (id_type != ID_PA) { + id_node->destroy(); + } + } + GHASH_FOREACH_END(); + GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, id_hash) + { + OBJECT_GUARDED_DELETE(id_node, IDDepsNode); + } + GHASH_FOREACH_END(); +#endif } /* Add new relationship between two nodes. */ @@ -389,9 +425,9 @@ DepsRelation::~DepsRelation() void Depsgraph::add_entry_tag(OperationDepsNode *node) { /* Sanity check. */ - if (!node) + if (node == NULL) { return; - + } /* Add to graph-level set of directly modified nodes to start searching from. * NOTE: this is necessary since we have several thousand nodes to play with... */ @@ -412,6 +448,25 @@ ID *Depsgraph::get_cow_id(const ID *id_orig) const { IDDepsNode *id_node = find_id_node(id_orig); if (id_node == NULL) { + /* This function is used from places where we expect ID to be either + * already a copy-on-write version or have a corresponding copy-on-write + * version. + * + * We try to enforce that in debug builds, for for release we play a bit + * safer game here. + */ + if ((id_orig->tag & LIB_TAG_COPY_ON_WRITE) == 0) { + /* TODO(sergey): This is nice sanity check to have, but it fails + * in following situations: + * + * - Material has link to texture, which is not needed by new + * shading system and hence can be ignored at construction. + * - Object or mesh has material at a slot which is not used (for + * example, object has material slot by materials are set to + * object data). + */ + // BLI_assert(!"Request for non-existing copy-on-write ID"); + } return (ID *)id_orig; } return id_node->id_cow; diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index 50c55bc0cf9..823a1935e18 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -102,7 +102,8 @@ struct Depsgraph { * Convenience wrapper to find node given just pointer + property. * * \param ptr: pointer to the data that node will represent - * \param prop: optional property affected - providing this effectively results in inner nodes being returned + * \param prop: optional property affected - providing this effectively + * results in inner nodes being returned * * \return A node matching the required characteristics if it exists * or NULL if no such node exists in the graph @@ -113,7 +114,7 @@ struct Depsgraph { TimeSourceDepsNode *find_time_source() const; IDDepsNode *find_id_node(const ID *id) const; - IDDepsNode *add_id_node(ID *id, const char *name = ""); + IDDepsNode *add_id_node(ID *id, bool do_tag = true, ID *id_cow_hint = NULL); void clear_id_nodes(); /* Add new relationship between two nodes. */ diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index 41934e3e4e6..e21c3d29aa5 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -257,6 +257,7 @@ void DEG_graph_tag_relations_update(Depsgraph *graph) /* Tag all relations for update. */ void DEG_relations_tag_update(Main *bmain) { + DEG_DEBUG_PRINTF("%s: Tagging relations for update.\n", __func__); for (Scene *scene = (Scene *)bmain->scene.first; scene != NULL; scene = (Scene *)scene->id.next) @@ -285,11 +286,6 @@ void DEG_scene_relations_update(Main *bmain, Scene *scene) return; } - /* Clear all previous nodes and operations. */ - graph->clear_all_nodes(); - graph->operations.clear(); - BLI_gset_clear(graph->entry_tags, NULL); - /* Build new nodes and relations. */ DEG_graph_build_from_scene(reinterpret_cast< ::Depsgraph * >(graph), bmain, @@ -348,7 +344,7 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle, int skip_forcefield, const char *name) { - ListBase *effectors = pdInitEffectors(scene, ob, NULL, effector_weights, false); + ListBase *effectors = pdInitEffectors(NULL, scene, ob, NULL, effector_weights, false); if (effectors) { for (EffectorCache *eff = (EffectorCache*)effectors->first; eff; eff = eff->next) { diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index 73a0428c264..77a32740524 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -56,7 +56,7 @@ extern "C" { /* Evaluation Context */ /* Create new evaluation context. */ -EvaluationContext *DEG_evaluation_context_new(int mode) +EvaluationContext *DEG_evaluation_context_new(eEvaluationMode mode) { EvaluationContext *eval_ctx = (EvaluationContext *)MEM_callocN(sizeof(EvaluationContext), @@ -70,11 +70,22 @@ EvaluationContext *DEG_evaluation_context_new(int mode) * Used by the areas which currently overrides the context or doesn't have * access to a proper one. */ -void DEG_evaluation_context_init(EvaluationContext *eval_ctx, int mode) +void DEG_evaluation_context_init(EvaluationContext *eval_ctx, + eEvaluationMode mode) { eval_ctx->mode = mode; } +void DEG_evaluation_context_init_from_scene(EvaluationContext *eval_ctx, + Scene *scene, + SceneLayer *scene_layer, + eEvaluationMode mode) +{ + DEG_evaluation_context_init(eval_ctx, mode); + eval_ctx->scene_layer = scene_layer; + eval_ctx->ctime = BKE_scene_frame_get(scene); +} + /* Free evaluation context. */ void DEG_evaluation_context_free(EvaluationContext *eval_ctx) { diff --git a/source/blender/depsgraph/intern/depsgraph_intern.h b/source/blender/depsgraph/intern/depsgraph_intern.h index 2d8e7dc841c..5ab090f3b3d 100644 --- a/source/blender/depsgraph/intern/depsgraph_intern.h +++ b/source/blender/depsgraph/intern/depsgraph_intern.h @@ -113,11 +113,23 @@ void deg_editors_id_update(struct Main *bmain, struct ID *id); void deg_editors_scene_update(struct Main *bmain, struct Scene *scene, bool updated); -#define DEG_DEBUG_PRINTF(...) \ - do { \ - if (G.debug & G_DEBUG_DEPSGRAPH) { \ - fprintf(stderr, __VA_ARGS__); \ - } \ +/* Tagging helpers ------------------------------------------------------ */ + +void lib_id_recalc_tag(struct Main *bmain, struct ID *id); +void lib_id_recalc_data_tag(struct Main *bmain, struct ID *id); + +#define DEG_DEBUG_PRINTF(...) \ + do { \ + if (G.debug & G_DEBUG_DEPSGRAPH) { \ + fprintf(stderr, __VA_ARGS__); \ + fflush(stderr); \ + } \ + } while (0) + +#define DEG_ERROR_PRINTF(...) \ + do { \ + fprintf(stderr, __VA_ARGS__); \ + fflush(stderr); \ } while (0) } // namespace DEG diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc index c0e50643102..0dd3cfaa783 100644 --- a/source/blender/depsgraph/intern/depsgraph_query.cc +++ b/source/blender/depsgraph/intern/depsgraph_query.cc @@ -53,9 +53,9 @@ extern "C" { # include "intern/eval/deg_eval_copy_on_write.h" #endif -bool DEG_id_type_tagged(Main *bmain, short idtype) +bool DEG_id_type_tagged(Main *bmain, short id_type) { - return bmain->id_tag_update[BKE_idcode_to_index(idtype)] != 0; + return bmain->id_tag_update[BKE_idcode_to_index(id_type)] != 0; } short DEG_get_eval_flags_for_id(Depsgraph *graph, ID *id) @@ -92,8 +92,7 @@ SceneLayer *DEG_get_evaluated_scene_layer(Depsgraph *graph) { Scene *scene = DEG_get_evaluated_scene(graph); if (scene != NULL) { - DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); - return BKE_scene_layer_context_active_ex_PLACEHOLDER(deg_graph->bmain, scene); + return BKE_scene_layer_context_active_PLACEHOLDER(scene); } return NULL; } @@ -105,8 +104,16 @@ Object *DEG_get_evaluated_object(Depsgraph *depsgraph, Object *object) ID *DEG_get_evaluated_id(struct Depsgraph *depsgraph, ID *id) { - DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph); - return deg_graph->get_cow_id(id); + /* TODO(sergey): This is a duplicate of Depsgraph::get_cow_id(), + * but here we never do assert, since we don't know nature of the + * incoming ID datablock. + */ + DEG::Depsgraph *deg_graph = (DEG::Depsgraph *)depsgraph; + DEG::IDDepsNode *id_node = deg_graph->find_id_node(id); + if (id_node == NULL) { + return id; + } + return id_node->id_cow; } /* ************************ DAG ITERATORS ********************* */ diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index abf4cba2617..38919fb890e 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -67,18 +67,17 @@ extern "C" { #include "intern/depsgraph_intern.h" #include "util/deg_util_foreach.h" +/* Define this in order to have more strict sanitization of what tagging flags + * are used for ID databnlocks. Ideally, we would always want this, but there + * are cases in generic modules (like IR remapping) where we don't want to spent + * lots of time trying to guess which components are to be updated. + */ +// #define STRICT_COMPONENT_TAGGING + /* *********************** */ /* Update Tagging/Flushing */ -/* Legacy depsgraph did some special trickery for things like particle systems - * when tagging ID for an update. Ideally that tagging needs to become obsolete - * in favor of havng dedicated node for that which gets tagged, but for until - * design of those areas is more clear we'll do the same legacy code here. - * - sergey - - */ -#define DEPSGRAPH_USE_LEGACY_TAGGING - -namespace { +namespace DEG { /* Data-Based Tagging ------------------------------- */ @@ -94,124 +93,275 @@ void lib_id_recalc_data_tag(Main *bmain, ID *id) DEG_id_type_tag(bmain, GS(id->name)); } +namespace { + void lib_id_recalc_tag_flag(Main *bmain, ID *id, int flag) { + /* This bit of code ensures legacy object->recalc flags are still filled in + * the same way as it was expected with the old dependency graph. + * + * This is because some areas like motion paths and likely some other + * physics baking process are doing manual scene update on all the frames, + * trying to minimize number of updates. + * + * But this flag will also let us to re-construct entry nodes for update + * after relations update and after layer visibility changes. + */ if (flag) { - /* This bit of code ensures legacy object->recalc flags - * are still filled in the same way as it was expected - * with the old dependency graph. - * - * This is because some areas like motion paths and likely - * some other physics baking process are doing manual scene - * update on all the frames, trying to minimize number of - * updates. - * - * But this flag will also let us to re-construct entry - * nodes for update after relations update and after layer - * visibility changes. - */ - short idtype = GS(id->name); - if (idtype == ID_OB) { + short id_type = GS(id->name); + if (id_type == ID_OB) { Object *object = (Object *)id; object->recalc |= (flag & OB_RECALC_ALL); } - - if (flag & OB_RECALC_OB) + if (flag & OB_RECALC_OB) { lib_id_recalc_tag(bmain, id); - if (flag & (OB_RECALC_DATA | PSYS_RECALC)) + } + if (flag & (OB_RECALC_DATA | PSYS_RECALC)) { lib_id_recalc_data_tag(bmain, id); + } } else { lib_id_recalc_tag(bmain, id); } } -#ifdef DEPSGRAPH_USE_LEGACY_TAGGING -void depsgraph_legacy_handle_update_tag(Main *bmain, ID *id, int flag) +/* Special tagging */ +void id_tag_update_special_zero_flag(Depsgraph *graph, IDDepsNode *id_node) { - if (flag) { - Object *object; - short idtype = GS(id->name); - if (idtype == ID_PA) { - ParticleSystem *psys; - for (object = (Object *)bmain->object.first; - object != NULL; - object = (Object *)object->id.next) - { - for (psys = (ParticleSystem *)object->particlesystem.first; - psys != NULL; - psys = (ParticleSystem *)psys->next) - { - if (&psys->part->id == id) { - DEG_id_tag_update_ex(bmain, &object->id, flag & OB_RECALC_ALL); - psys->recalc |= (flag & PSYS_RECALC); - } - } + /* NOTE: Full ID node update for now, need to minimize that i9n the future. */ + id_node->tag_update(graph); +} + +/* Tag corresponding to OB_RECALC_OB. */ +void id_tag_update_object_transform(Depsgraph *graph, IDDepsNode *id_node) +{ + ComponentDepsNode *transform_comp = + id_node->find_component(DEG_NODE_TYPE_TRANSFORM); + if (transform_comp == NULL) { +#ifdef STRICT_COMPONENT_TAGGING + DEG_ERROR_PRINTF("ERROR: Unable to find transform component for %s\n", + id_node->id_orig->name); + BLI_assert(!"This is not supposed to happen!"); +#endif + return; + } + transform_comp->tag_update(graph); +} + +/* Tag corresponding to OB_RECALC_DATA. */ +void id_tag_update_object_data(Depsgraph *graph, IDDepsNode *id_node) +{ + const short id_type = GS(id_node->id_orig->name); + ComponentDepsNode *data_comp = NULL; + switch (id_type) { + case ID_OB: + { + const Object *object = (Object *)id_node->id_orig; + switch (object->type) { + case OB_MESH: + case OB_CURVE: + case OB_SURF: + case OB_FONT: + case OB_MBALL: + data_comp = id_node->find_component(DEG_NODE_TYPE_GEOMETRY); + break; + case OB_ARMATURE: + data_comp = id_node->find_component(DEG_NODE_TYPE_EVAL_POSE); + break; + /* TODO(sergey): More cases here? */ } + break; } + case ID_ME: + data_comp = id_node->find_component(DEG_NODE_TYPE_GEOMETRY); + break; + case ID_PA: + return; } -} + if (data_comp == NULL) { +#ifdef STRICT_COMPONENT_TAGGING + DEG_ERROR_PRINTF("ERROR: Unable to find data component for %s\n", + id_node->id_orig->name); + BLI_assert(!"This is not supposed to happen!"); #endif + return; + } + data_comp->tag_update(graph); + /* Special legacy compatibility code, tag data ID for update when object + * is tagged for data update. + */ + if (id_type == ID_OB) { + Object *object = (Object *)id_node->id_orig; + ID *data_id = (ID *)object->data; + if (data_id != NULL) { + IDDepsNode *data_id_node = graph->find_id_node(data_id); + // BLI_assert(data_id_node != NULL); + /* TODO(sergey): Do we want more granular tags here? */ + /* TODO(sergey): Hrm, during some operations it's possible to have + * object node existing but not it's data. For example, when making + * objects local. This is valid situation, but how can we distinguish + * that from someone trying to do stupid things with dependency + * graph? + */ + if (data_id_node != NULL) { + data_id_node->tag_update(graph); + } + } + } +} -#ifdef WITH_COPY_ON_WRITE -void id_tag_copy_on_write_update(Main *bmain, Depsgraph *graph, ID *id) +/* Tag corresponding to OB_RECALC_TIME. */ +void id_tag_update_object_time(Depsgraph *graph, IDDepsNode *id_node) { - lib_id_recalc_tag(bmain, id); - DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); - DEG::IDDepsNode *id_node = deg_graph->find_id_node(id); - DEG::ComponentDepsNode *cow_comp = - id_node->find_component(DEG::DEG_NODE_TYPE_COPY_ON_WRITE); - DEG::OperationDepsNode *cow_node = cow_comp->get_entry_operation(); - cow_node->tag_update(deg_graph); - cow_node->flag |= DEG::DEPSOP_FLAG_SKIP_FLUSH; + ComponentDepsNode *animation_comp = + id_node->find_component(DEG_NODE_TYPE_ANIMATION); + if (animation_comp == NULL) { + /* It's not necessarily we've got animation component in cases when + * we are tagging for time updates. + */ + return; + } + animation_comp->tag_update(graph); + /* TODO(sergey): More components to tag here? */ } -#endif -} /* namespace */ +void id_tag_update_particle(Depsgraph *graph, IDDepsNode *id_node, int tag) +{ + ComponentDepsNode *particle_comp = + id_node->find_component(DEG_NODE_TYPE_PARAMETERS); + ParticleSettings *particle_settings = (ParticleSettings *)id_node->id_orig; + particle_settings->recalc |= (tag & PSYS_RECALC); + if (particle_comp == NULL) { +#ifdef STRICT_COMPONENT_TAGGING + DEG_ERROR_PRINTF("ERROR: Unable to find particle component for %s\n", + id_node->id_orig->name); + BLI_assert(!"This is not supposed to happen!"); +#endif + return; + } + particle_comp->tag_update(graph); +} -/* Tag all nodes in ID-block for update. - * This is a crude measure, but is most convenient for old code. - */ -void DEG_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id) +void id_tag_update_shading(Depsgraph *graph, IDDepsNode *id_node) { - DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); - DEG::IDDepsNode *node = deg_graph->find_id_node(id); - lib_id_recalc_tag(bmain, id); - if (node != NULL) { - node->tag_update(deg_graph); + ComponentDepsNode *shading_comp = + id_node->find_component(DEG_NODE_TYPE_SHADING); + if (shading_comp == NULL) { +#ifdef STRICT_COMPONENT_TAGGING + DEG_ERROR_PRINTF("ERROR: Unable to find shading component for %s\n", + id_node->id_orig->name); + BLI_assert(!"This is not supposed to happen!"); +#endif + return; } + shading_comp->tag_update(graph); +} + +#ifdef WITH_COPY_ON_WRITE +/* Tag corresponding to DEG_TAG_COPY_ON_WRITE. */ +void id_tag_update_copy_on_write(Depsgraph *graph, IDDepsNode *id_node) +{ + ComponentDepsNode *cow_comp = + id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE); + OperationDepsNode *cow_node = cow_comp->get_entry_operation(); + cow_node->tag_update(graph); } +#endif -/* Tag nodes related to a specific piece of data */ -void DEG_graph_data_tag_update(Depsgraph *graph, const PointerRNA *ptr) +void deg_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, int flag) { - DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); - DEG::DepsNode *node = deg_graph->find_node_from_pointer(ptr, NULL); - if (node != NULL) { - node->tag_update(deg_graph); + Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); + IDDepsNode *id_node = deg_graph->find_id_node(id); + /* Make sure legacy flags are all nicely update. */ + lib_id_recalc_tag_flag(bmain, id, flag); + if (id_node == NULL) { + /* Shouldn't happen, but better be sure here. */ + return; } - else { - printf("Missing node in %s\n", __func__); - BLI_assert(!"Shouldn't happens since it'll miss crucial update."); + /* Tag components based on flags. */ + if (flag == 0) { + id_tag_update_special_zero_flag(graph, id_node); + return; + } + if (flag & OB_RECALC_OB) { + id_tag_update_object_transform(graph, id_node); + } + if (flag & OB_RECALC_DATA) { + id_tag_update_object_data(graph, id_node); +#ifdef WITH_COPY_ON_WRITE + if (flag & DEG_TAG_COPY_ON_WRITE) { + const short id_type = GS(id_node->id_orig->name); + if (id_type == ID_OB) { + Object *object = (Object *)id_node->id_orig; + ID *ob_data = (ID *)object->data; + DEG_id_tag_update_ex(bmain, ob_data, flag); + } + } +#endif } + if (flag & OB_RECALC_TIME) { + id_tag_update_object_time(graph, id_node); + } + if (flag & PSYS_RECALC) { + id_tag_update_particle(graph, id_node, flag); + } + if (flag & DEG_TAG_SHADING_UPDATE) { + id_tag_update_shading(graph, id_node); + } +#ifdef WITH_COPY_ON_WRITE + if (flag & DEG_TAG_COPY_ON_WRITE) { + id_tag_update_copy_on_write(graph, id_node); + } +#endif } -/* Tag nodes related to a specific property. */ -void DEG_graph_property_tag_update(Depsgraph *graph, - const PointerRNA *ptr, - const PropertyRNA *prop) +void deg_id_tag_update(Main *bmain, ID *id, int flag) { - DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); - DEG::DepsNode *node = deg_graph->find_node_from_pointer(ptr, prop); - if (node != NULL) { - node->tag_update(deg_graph); + lib_id_recalc_tag_flag(bmain, id, flag); + for (Scene *scene = (Scene *)bmain->scene.first; + scene != NULL; + scene = (Scene *)scene->id.next) + { + if (scene->depsgraph_legacy != NULL) { + Depsgraph *graph = (Depsgraph *)scene->depsgraph_legacy; + deg_graph_id_tag_update(bmain, graph, id, flag); + } } - else { - printf("Missing node in %s\n", __func__); - BLI_assert(!"Shouldn't happens since it'll miss crucial update."); +} + +void deg_graph_on_visible_update(Main *bmain, Scene *scene, Depsgraph *graph) +{ + /* Make sure objects are up to date. */ + GHASH_FOREACH_BEGIN(DEG::IDDepsNode *, id_node, graph->id_hash) + { + const short id_type = GS(id_node->id_orig->name); + if (id_type != ID_OB) { + /* Ignore non-object nodes on visibility changes. */ + continue; + } + int flag = 0; + /* We only tag components which needs an update. Tagging everything is + * not a good idea because that might reset particles cache (or any + * other type of cache). + * + * TODO(sergey): Need to generalize this somehow. + */ + if (id_type == ID_OB) { + flag |= OB_RECALC_OB | OB_RECALC_DATA | DEG_TAG_COPY_ON_WRITE; + } + deg_graph_id_tag_update(bmain, graph, id_node->id_orig, flag); } + GHASH_FOREACH_END(); + /* Make sure collection properties are up to date. */ + IDDepsNode *scene_id_node = graph->find_id_node(&scene->id); + BLI_assert(scene_id_node != NULL); + scene_id_node->tag_update(graph); } +} /* namespace */ + +} // namespace DEG + /* Tag given ID for an update in all the dependency graphs. */ void DEG_id_tag_update(ID *id, int flag) { @@ -225,56 +375,13 @@ void DEG_id_tag_update_ex(Main *bmain, ID *id, int flag) return; } DEG_DEBUG_PRINTF("%s: id=%s flag=%d\n", __func__, id->name, flag); - lib_id_recalc_tag_flag(bmain, id, flag); - for (Scene *scene = (Scene *)bmain->scene.first; - scene != NULL; - scene = (Scene *)scene->id.next) - { - if (scene->depsgraph_legacy) { - Depsgraph *graph = scene->depsgraph_legacy; - if (flag == 0) { - /* TODO(sergey): Currently blender is still tagging IDs - * for recalc just using flag=0. This isn't totally correct - * but we'd better deal with such cases and don't fail. - */ - DEG_graph_id_tag_update(bmain, graph, id); - continue; - } - if (flag & OB_RECALC_DATA && GS(id->name) == ID_OB) { - Object *object = (Object *)id; - if (object->data != NULL) { - DEG_graph_id_tag_update(bmain, - graph, - (ID *)object->data); - } - } - if (flag & (OB_RECALC_OB | OB_RECALC_DATA)) { - DEG_graph_id_tag_update(bmain, graph, id); - } - else if (flag & OB_RECALC_TIME) { - DEG_graph_id_tag_update(bmain, graph, id); - } - else if (flag & DEG_TAG_COPY_ON_WRITE) { -#ifdef WITH_COPY_ON_WRITE - id_tag_copy_on_write_update(bmain, graph, id); -#endif - } - } - } - -#ifdef DEPSGRAPH_USE_LEGACY_TAGGING - /* Special handling from the legacy depsgraph. - * TODO(sergey): Need to get rid of those once all the areas - * are re-formulated in terms of franular nodes. - */ - depsgraph_legacy_handle_update_tag(bmain, id, flag); -#endif + DEG::deg_id_tag_update(bmain, id, flag); } /* Tag given ID type for update. */ -void DEG_id_type_tag(Main *bmain, short idtype) +void DEG_id_type_tag(Main *bmain, short id_type) { - if (idtype == ID_NT) { + if (id_type == ID_NT) { /* Stupid workaround so parent datablocks of nested nodetree get looped * over when we loop over tagged datablock types. */ @@ -285,7 +392,7 @@ void DEG_id_type_tag(Main *bmain, short idtype) DEG_id_type_tag(bmain, ID_SCE); } - bmain->id_tag_update[BKE_idcode_to_index(idtype)] = 1; + bmain->id_tag_update[BKE_idcode_to_index(id_type)] = 1; } /* Recursively push updates out to all nodes dependent on this, @@ -304,13 +411,8 @@ void DEG_ids_flush_tagged(Main *bmain, Scene *scene) /* Update dependency graph when visible scenes/layers changes. */ void DEG_graph_on_visible_update(Main *bmain, Scene *scene) { - (void) bmain; - DEG::Depsgraph *graph = reinterpret_cast<DEG::Depsgraph *>(scene->depsgraph_legacy); - GHASH_FOREACH_BEGIN(DEG::IDDepsNode *, id_node, graph->id_hash) - { - id_node->tag_update(graph); - } - GHASH_FOREACH_END(); + DEG::Depsgraph *graph = (DEG::Depsgraph *)scene->depsgraph_legacy; + DEG::deg_graph_on_visible_update(bmain, scene, graph); } void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time)) diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc index eab1913727d..405c8e87339 100644 --- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc +++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc @@ -98,38 +98,52 @@ static const char *stringify_opcode(eDepsOperation_Code opcode) { switch (opcode) { #define STRINGIFY_OPCODE(name) case DEG_OPCODE_##name: return #name + /* Generic Operations. */ STRINGIFY_OPCODE(OPERATION); + STRINGIFY_OPCODE(PARAMETERS_EVAL); STRINGIFY_OPCODE(PLACEHOLDER); + /* Animation, Drivers, etc. */ STRINGIFY_OPCODE(ANIMATION); STRINGIFY_OPCODE(DRIVER); + /* Transform. */ STRINGIFY_OPCODE(TRANSFORM_LOCAL); STRINGIFY_OPCODE(TRANSFORM_PARENT); STRINGIFY_OPCODE(TRANSFORM_CONSTRAINTS); + STRINGIFY_OPCODE(TRANSFORM_FINAL); + STRINGIFY_OPCODE(TRANSFORM_OBJECT_UBEREVAL); + /* Rigid body. */ STRINGIFY_OPCODE(RIGIDBODY_REBUILD); STRINGIFY_OPCODE(RIGIDBODY_SIM); - STRINGIFY_OPCODE(TRANSFORM_RIGIDBODY); - STRINGIFY_OPCODE(TRANSFORM_FINAL); - STRINGIFY_OPCODE(OBJECT_UBEREVAL); + STRINGIFY_OPCODE(RIGIDBODY_TRANSFORM_COPY); + /* Geometry. */ STRINGIFY_OPCODE(GEOMETRY_UBEREVAL); STRINGIFY_OPCODE(GEOMETRY_PATH); + /* Pose. */ STRINGIFY_OPCODE(POSE_INIT); STRINGIFY_OPCODE(POSE_DONE); STRINGIFY_OPCODE(POSE_IK_SOLVER); STRINGIFY_OPCODE(POSE_SPLINE_IK_SOLVER); + /* Bone. */ STRINGIFY_OPCODE(BONE_LOCAL); STRINGIFY_OPCODE(BONE_POSE_PARENT); STRINGIFY_OPCODE(BONE_CONSTRAINTS); STRINGIFY_OPCODE(BONE_READY); STRINGIFY_OPCODE(BONE_DONE); - STRINGIFY_OPCODE(PSYS_EVAL); - + /* Particles. */ + STRINGIFY_OPCODE(PARTICLE_SYSTEM_EVAL_INIT); + STRINGIFY_OPCODE(PARTICLE_SYSTEM_EVAL); + STRINGIFY_OPCODE(PARTICLE_SETTINGS_EVAL); + STRINGIFY_OPCODE(PARTICLE_SETTINGS_RECALC_CLEAR); + /* Collections. */ STRINGIFY_OPCODE(SCENE_LAYER_INIT); STRINGIFY_OPCODE(SCENE_LAYER_EVAL); STRINGIFY_OPCODE(SCENE_LAYER_DONE); - + /* Copy on write. */ STRINGIFY_OPCODE(COPY_ON_WRITE); - + /* Shading. */ STRINGIFY_OPCODE(SHADING); + STRINGIFY_OPCODE(MATERIAL_UPDATE); + STRINGIFY_OPCODE(WORLD_UPDATE); case DEG_NUM_OPCODES: return "SpecialCase"; #undef STRINGIFY_OPCODE diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h index 15b6f9bd00e..ba776d5ebd5 100644 --- a/source/blender/depsgraph/intern/depsgraph_types.h +++ b/source/blender/depsgraph/intern/depsgraph_types.h @@ -136,11 +136,14 @@ typedef enum eDepsNode_Type { /* Identifiers for common operations (as an enum). */ typedef enum eDepsOperation_Code { - /* Generic Operations ------------------------------ */ + /* Generic Operations. ------------------------------ */ /* Placeholder for operations which don't need special mention */ DEG_OPCODE_OPERATION = 0, + /* Generic parameters evaluation. */ + DEG_OPCODE_PARAMETERS_EVAL, + // XXX: Placeholder while porting depsgraph code DEG_OPCODE_PLACEHOLDER, @@ -150,7 +153,7 @@ typedef enum eDepsOperation_Code { /* Driver */ DEG_OPCODE_DRIVER, - /* Transform --------------------------------------- */ + /* Transform. -------------------------------------- */ /* Transform entry point - local transforms only */ DEG_OPCODE_TRANSFORM_LOCAL, /* Parenting */ @@ -160,22 +163,22 @@ typedef enum eDepsOperation_Code { /* Transform exit point */ DEG_OPCODE_TRANSFORM_FINAL, /* Handle object-level updates, mainly proxies hacks and recalc flags. */ - DEG_OPCODE_OBJECT_UBEREVAL, + DEG_OPCODE_TRANSFORM_OBJECT_UBEREVAL, - /* Rigid body -------------------------------------- */ + /* Rigid body. -------------------------------------- */ /* Perform Simulation */ DEG_OPCODE_RIGIDBODY_REBUILD, DEG_OPCODE_RIGIDBODY_SIM, /* Copy results to object */ - DEG_OPCODE_TRANSFORM_RIGIDBODY, + DEG_OPCODE_RIGIDBODY_TRANSFORM_COPY, - /* Geometry ---------------------------------------- */ + /* Geometry. ---------------------------------------- */ /* Evaluate the whole geometry, including modifiers. */ DEG_OPCODE_GEOMETRY_UBEREVAL, /* Curve Objects - Path Calculation (used for path-following tools, */ DEG_OPCODE_GEOMETRY_PATH, - /* Pose -------------------------------------------- */ + /* Pose. -------------------------------------------- */ /* Init IK Trees, etc. */ DEG_OPCODE_POSE_INIT, /* Free IK Trees + Compute Deform Matrices */ @@ -184,7 +187,7 @@ typedef enum eDepsOperation_Code { DEG_OPCODE_POSE_IK_SOLVER, DEG_OPCODE_POSE_SPLINE_IK_SOLVER, - /* Bone -------------------------------------------- */ + /* Bone. -------------------------------------------- */ /* Bone local transforms - entry point */ DEG_OPCODE_BONE_LOCAL, /* Pose-space conversion (includes parent + restpose, */ @@ -205,20 +208,25 @@ typedef enum eDepsOperation_Code { DEG_OPCODE_BONE_READY, DEG_OPCODE_BONE_DONE, - /* Particles --------------------------------------- */ + /* Particles. --------------------------------------- */ /* Particle System evaluation. */ - DEG_OPCODE_PSYS_EVAL, + DEG_OPCODE_PARTICLE_SYSTEM_EVAL_INIT, + DEG_OPCODE_PARTICLE_SYSTEM_EVAL, + DEG_OPCODE_PARTICLE_SETTINGS_EVAL, + DEG_OPCODE_PARTICLE_SETTINGS_RECALC_CLEAR, - /* Collections ------------------------------------- */ + /* Collections. ------------------------------------- */ DEG_OPCODE_SCENE_LAYER_INIT, DEG_OPCODE_SCENE_LAYER_EVAL, DEG_OPCODE_SCENE_LAYER_DONE, - /* Copy on Write ------------------------- */ + /* Copy on Write. ------------------------------------ */ DEG_OPCODE_COPY_ON_WRITE, - /* Shading operations ------------------------- */ + /* Shading. ------------------------------------------- */ DEG_OPCODE_SHADING, + DEG_OPCODE_MATERIAL_UPDATE, + DEG_OPCODE_WORLD_UPDATE, DEG_NUM_OPCODES, } eDepsOperation_Code; diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 15ad6b8054d..120785ac548 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -38,7 +38,10 @@ #include "BLI_task.h" #include "BLI_ghash.h" +#include "DNA_object_types.h" + #include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" #include "atomic_ops.h" @@ -275,6 +278,7 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx, /* Set time for the current graph evaluation context. */ TimeSourceDepsNode *time_src = graph->find_time_source(); + eval_ctx->scene_layer = DEG_get_evaluated_scene_layer((::Depsgraph *)graph); eval_ctx->ctime = time_src->cfra; /* XXX could use a separate pool for each eval context */ diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index 663caf5d716..3ed93ea5677 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -72,11 +72,14 @@ extern "C" { # include "DNA_world_types.h" #endif +#include "BKE_action.h" #include "BKE_editmesh.h" #include "BKE_library_query.h" +#include "BKE_object.h" } #include "intern/depsgraph.h" +#include "intern/builder/deg_builder_nodes.h" #include "intern/nodes/deg_node.h" namespace DEG { @@ -110,7 +113,17 @@ void nested_id_hack_discard_pointers(ID *id_cow) SPECIAL_CASE(ID_LS, FreestyleLineStyle, nodetree) SPECIAL_CASE(ID_LA, Lamp, nodetree) SPECIAL_CASE(ID_MA, Material, nodetree) +#if 0 SPECIAL_CASE(ID_SCE, Scene, nodetree) +#else + case ID_SCE: + { + Scene *scene_cow = (Scene *)id_cow; + scene_cow->nodetree = NULL; + BLI_listbase_clear(&scene_cow->base); + break; + } +#endif SPECIAL_CASE(ID_TE, Tex, nodetree) SPECIAL_CASE(ID_WO, World, nodetree) @@ -142,7 +155,17 @@ const ID *nested_id_hack_get_discarded_pointers(NestedIDHackTempStorage *storage SPECIAL_CASE(ID_LS, FreestyleLineStyle, nodetree, linestyle) SPECIAL_CASE(ID_LA, Lamp, nodetree, lamp) SPECIAL_CASE(ID_MA, Material, nodetree, material) +#if 0 SPECIAL_CASE(ID_SCE, Scene, nodetree, scene) +#else + case ID_SCE: + { + storage->scene = *(Scene *)id; + storage->scene.nodetree = NULL; + BLI_listbase_clear(&storage->scene.base); + return &storage->scene.id; + } +#endif SPECIAL_CASE(ID_TE, Tex, nodetree, tex) SPECIAL_CASE(ID_WO, World, nodetree, world) @@ -256,6 +279,21 @@ bool id_copy_no_main(const ID *id, ID **newid) return result; } +void layer_collections_sync_flags(ListBase *layer_collections_dst, + const ListBase *layer_collections_src) +{ + LayerCollection *layer_collection_dst = (LayerCollection *)layer_collections_dst->first; + const LayerCollection *layer_collection_src = (const LayerCollection *)layer_collections_src->first; + while (layer_collection_dst != NULL) { + layer_collection_dst->flag = layer_collection_src->flag; + layer_collections_sync_flags(&layer_collection_dst->layer_collections, + &layer_collection_src->layer_collections); + /* TODO(sergey): Overrides. */ + layer_collection_dst = layer_collection_dst->next; + layer_collection_src = layer_collection_src->next; + } +} + /* Similar to BKE_scene_copy() but does not require main. * * TODO(sergey): Get rid of this once T51804 is handled. @@ -278,6 +316,18 @@ Scene *scene_copy_no_main(Scene *scene) (Scene *)id_for_copy, SCE_COPY_LINK_OB); + /* TODO(sergey): Make this part of BKE_scene_copy(). */ + { + SceneLayer *new_scene_layer = (SceneLayer *)new_scene->render_layers.first; + const SceneLayer *scene_layer = (const SceneLayer *)scene->render_layers.first; + while (new_scene_layer != NULL) { + layer_collections_sync_flags(&new_scene_layer->layer_collections, + &scene_layer->layer_collections); + new_scene_layer = new_scene_layer->next; + scene_layer = scene_layer->next; + } + } + #ifdef NESTED_ID_NASTY_WORKAROUND nested_id_hack_restore_pointers(&scene->id, &new_scene->id); #endif @@ -286,27 +336,6 @@ Scene *scene_copy_no_main(Scene *scene) return new_scene; } -/* Callback for BKE_library_foreach_ID_link which remaps original ID pointer - * with the one created by CoW system. - */ -int foreach_libblock_remap_callback(void *user_data, - ID * /*id_self*/, - ID **id_p, - int /*cb_flag*/) -{ - Depsgraph *depsgraph = (Depsgraph *)user_data; - if (*id_p != NULL) { - const ID *id_orig = *id_p; - ID *id_cow = depsgraph->get_cow_id(id_orig); - if (id_cow != NULL) { - DEG_COW_PRINT(" Remapping datablock for %s: id_orig=%p id_cow=%p\n", - id_orig->name, id_orig, id_cow); - *id_p = id_cow; - } - } - return IDWALK_RET_NOP; -} - /* Check whether given ID is expanded or still a shallow copy. */ BLI_INLINE bool check_datablock_expanded(const ID *id_cow) { @@ -324,6 +353,105 @@ static bool check_datablock_expanded_at_construction(const ID *id_orig) (id_type == ID_AR); } +/* Those are datablocks which are not covered by dependency graph and hence + * does not need any remapping or anything. + * + * TODO(sergey): How to make it more robust for the future, so we don't have + * to maintain exception lists all over the code? + */ +static bool check_datablocks_copy_on_writable(const ID *id_orig) +{ + const short id_type = GS(id_orig->name); + /* We shouldn't bother if copied ID is same as original one. */ + if (!deg_copy_on_write_is_needed(id_orig)) { + return false; + } + return !ELEM(id_type, ID_BR, + ID_LS, + ID_AC, + ID_GR, + ID_PAL); +} + +/* Callback for BKE_library_foreach_ID_link which remaps original ID pointer + * with the one created by CoW system. + */ + +struct RemapCallbackUserData { + /* Dependency graph for which remapping is happening. */ + const Depsgraph *depsgraph; + /* Temporarily allocated memory for copying purposes. This ID will + * be discarded after expanding is done, so need to make sure temp_id + * is replaced with proper real_id. + * + * NOTE: This is due to our logic of "inplace" duplication, where we + * use generic duplication routines (which gives us new ID) which then + * is followed with copying data to a placeholder we prepared before and + * discarding pointer returned by duplication routines. + */ + const ID *temp_id; + ID *real_id; + /* Create placeholder for ID nodes for cases when we need to remap original + * ID to it[s CoW version but we don't have required ID node yet. + * + * This happens when expansion happens a ta construction time. + */ + DepsgraphNodeBuilder *node_builder; + bool create_placeholders; +}; + +int foreach_libblock_remap_callback(void *user_data_v, + ID *id_self, + ID **id_p, + int /*cb_flag*/) +{ + RemapCallbackUserData *user_data = (RemapCallbackUserData *)user_data_v; + const Depsgraph *depsgraph = user_data->depsgraph; + if (*id_p != NULL) { + ID *id_orig = *id_p; + if (id_orig == user_data->temp_id) { + DEG_COW_PRINT(" Remapping datablock for %s: id_temp=%p id_cow=%p\n", + id_orig->name, id_orig, user_data->real_id); + *id_p = user_data->real_id; + } + else if (check_datablocks_copy_on_writable(id_orig)) { + ID *id_cow; + if (user_data->create_placeholders) { + /* Special workaround to stop creating temp datablocks for + * objects which are coming from scene's collection and which + * are never linked to any of layers. + * + * TODO(sergey): Ideally we need to tell ID looper to ignore + * those or at least make it more reliable check where the + * pointer is coming from. + */ + const short id_type = GS(id_orig->name); + const short id_type_self = GS(id_self->name); + if (id_type == ID_OB && id_type_self == ID_SCE) { + IDDepsNode *id_node = depsgraph->find_id_node(id_orig); + if (id_node == NULL) { + id_cow = id_orig; + } + else { + id_cow = id_node->id_cow; + } + } + else { + id_cow = user_data->node_builder->ensure_cow_id(id_orig); + } + } + else { + id_cow = depsgraph->get_cow_id(id_orig); + } + BLI_assert(id_cow != NULL); + DEG_COW_PRINT(" Remapping datablock for %s: id_orig=%p id_cow=%p\n", + id_orig->name, id_orig, id_cow); + *id_p = id_cow; + } + } + return IDWALK_RET_NOP; +} + /* Do some special treatment of data transfer from original ID to it's * CoW complementary part. * @@ -340,9 +468,11 @@ void update_special_pointers(const Depsgraph *depsgraph, * new copy of the object. */ Object *object_cow = (Object *)id_cow; + const Object *object_orig = (const Object *)id_orig; (void) object_cow; /* Ignored for release builds. */ BLI_assert(object_cow->derivedFinal == NULL); BLI_assert(object_cow->derivedDeform == NULL); + object_cow->mode = object_orig->mode; break; } case ID_ME: @@ -380,6 +510,73 @@ void update_special_pointers(const Depsgraph *depsgraph, } } +/* Update copy-on-write version of scene from original scene. */ +void update_copy_on_write_scene(const Depsgraph *depsgraph, + Scene *scene_cow, + const Scene *scene_orig) +{ + // Some non-pointer data sync, current frame for now. + // TODO(sergey): Are we missing something here? + scene_cow->r.cfra = scene_orig->r.cfra; + scene_cow->r.subframe = scene_orig->r.subframe; + // Update bases. + const SceneLayer *sl_orig = (SceneLayer *)scene_orig->render_layers.first; + SceneLayer *sl_cow = (SceneLayer *)scene_cow->render_layers.first; + while (sl_orig != NULL) { + // Update pointers to active base. + if (sl_orig->basact == NULL) { + sl_cow->basact = NULL; + } + else { + const Object *obact_orig = sl_orig->basact->object; + Object *obact_cow = (Object *)depsgraph->get_cow_id(&obact_orig->id); + sl_cow->basact = BKE_scene_layer_base_find(sl_cow, obact_cow); + } + // Update base flags. + // + // TODO(sergey): We should probably check visibled/selectabled + // flag here? + const Base *base_orig = (Base *)sl_orig->object_bases.first; + Base *base_cow = (Base *)sl_cow->object_bases.first;; + while (base_orig != NULL) { + base_cow->flag = base_orig->flag; + base_orig = base_orig->next; + base_cow = base_cow->next; + } + sl_orig = sl_orig->next; + sl_cow = sl_cow->next; + } + // Update edit object pointer. + if (scene_orig->obedit != NULL) { + scene_cow->obedit = (Object *)depsgraph->get_cow_id(&scene_orig->obedit->id); + } + else { + scene_cow->obedit = NULL; + } + /* Synchronize active render engine. */ + BLI_strncpy_utf8(scene_cow->r.engine, + scene_orig->r.engine, + sizeof(scene_cow->r.engine)); + /* TODO(sergey): What else do we need here? */ +} + +/* Update copy-on-write version of armature object from original scene. */ +void update_copy_on_write_object(const Depsgraph * /*depsgraph*/, + Object *object_cow, + const Object *object_orig) +{ + /* TODO(sergey): This function might be split into a smaller ones, + * reused for different updates. And maybe even moved to BKE. + */ + /* Update armature/pose related flags. */ + bPose *pose_cow = object_cow->pose; + const bPose *pose_orig = object_orig->pose; + extract_pose_from_pose(pose_cow, pose_orig); + /* Update object itself. */ + BKE_object_transform_copy(object_cow, object_orig); + object_cow->mode = object_orig->mode; +} + /* Update copy-on-write version of datablock from it's original ID without re-building * the whole datablock from scratch. * @@ -389,52 +586,36 @@ void update_special_pointers(const Depsgraph *depsgraph, void update_copy_on_write_datablock(const Depsgraph *depsgraph, const ID *id_orig, ID *id_cow) { - if (GS(id_orig->name) == ID_SCE) { - const Scene *scene_orig = (const Scene *)id_orig; - Scene *scene_cow = (Scene *)id_cow; - // Some non-pointer data sync, current frame for now. - // TODO(sergey): Are we missing something here? - scene_cow->r.cfra = scene_orig->r.cfra; - scene_cow->r.subframe = scene_orig->r.subframe; - // Update bases. - const SceneLayer *sl_orig = (SceneLayer *)scene_orig->render_layers.first; - SceneLayer *sl_cow = (SceneLayer *)scene_cow->render_layers.first; - while (sl_orig != NULL) { - // Update pointers to active base. - if (sl_orig->basact == NULL) { - sl_cow->basact = NULL; - } - else { - const Object *obact_orig = sl_orig->basact->object; - Object *obact_cow = (Object *)depsgraph->get_cow_id(&obact_orig->id); - sl_cow->basact = BKE_scene_layer_base_find(sl_cow, obact_cow); - } - // Update base flags. - // - // TODO(sergey): We should probably check visibled/selectabled - // flag here? - const Base *base_orig = (Base *)sl_orig->object_bases.first; - Base *base_cow = (Base *)sl_cow->object_bases.first;; - while (base_orig != NULL) { - base_cow->flag = base_orig->flag; - base_orig = base_orig->next; - base_cow = base_cow->next; - } - sl_orig = sl_orig->next; - sl_cow = sl_cow->next; - } - // Update edit object pointer. - if (scene_orig->obedit != NULL) { - scene_cow->obedit = (Object *)depsgraph->get_cow_id(&scene_orig->obedit->id); + bool ok = false; + const short id_type = GS(id_orig->name); + switch (id_type) { + case ID_SCE: { + const Scene *scene_orig = (const Scene *)id_orig; + Scene *scene_cow = (Scene *)id_cow; + update_copy_on_write_scene(depsgraph, scene_cow, scene_orig); + ok = true; + break; } - else { - scene_cow->obedit = NULL; + case ID_OB: { + const Object *object_orig = (const Object *)id_orig; + Object *object_cow = (Object *)id_cow; + if (object_orig->type == OB_ARMATURE) { + update_copy_on_write_object(depsgraph, + object_cow, + object_orig); + ok = true; + } + break; } - // TODO(sergey): Things which are still missing here: - // - Active render engine. - // - Something else? + case ID_AR: + /* Nothing to do currently. */ + ok = true; + break; } // TODO(sergey): Other ID types here. + if (!ok) { + BLI_assert(!"Missing update logic of expanded datablock"); + } } /* This callback is used to validate that all nested ID datablocks are @@ -449,7 +630,7 @@ int foreach_libblock_validate_callback(void *user_data, if (*id_p != NULL) { if (!check_datablock_expanded(*id_p)) { data->is_valid = false; - /* TODO(sergey_: Store which is is not valid? */ + /* TODO(sergey): Store which is is not valid? */ } } return IDWALK_RET_NOP; @@ -463,14 +644,30 @@ int foreach_libblock_validate_callback(void *user_data, * NOTE: Expects that CoW datablock is empty. */ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph, - const IDDepsNode *id_node) + const IDDepsNode *id_node, + DepsgraphNodeBuilder *node_builder, + bool create_placeholders) { + BLI_assert(!create_placeholders || + check_datablock_expanded_at_construction(id_node->id_orig)); const ID *id_orig = id_node->id_orig; ID *id_cow = id_node->id_cow; + /* No need to expand such datablocks, their copied ID is same as original + * one already. + */ + if (!deg_copy_on_write_is_needed(id_orig)) { + return id_cow; + } DEG_COW_PRINT("Expanding datablock for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow); /* Sanity checks. */ - BLI_assert(check_datablock_expanded(id_cow) == false); + /* NOTE: Disabled for now, conflicts when re-using evaluated datablock when + * rebuilding dependencies. + */ + if (check_datablock_expanded(id_cow) && create_placeholders) { + deg_free_copy_on_write_datablock(id_cow); + } + // BLI_assert(check_datablock_expanded(id_cow) == false); /* Copy data from original ID to a copied version. */ /* TODO(sergey): Avoid doing full ID copy somehow, make Mesh to reference * original geometry arrays for until those are modified. @@ -484,12 +681,17 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph, * - We don't want bmain's content to be freed when main is freed. */ bool done = false; + /* Need to make sure the possibly temporary allocated memory is correct for + * until we are fully done with remapping original pointers with copied on + * write ones. + */ + ID *newid = NULL; /* First we handle special cases which are not covered by id_copy() yet. * or cases where we want to do something smarter than simple datablock * copy. */ - const short type = GS(id_orig->name); - switch (type) { + const short id_type = GS(id_orig->name); + switch (id_type) { case ID_SCE: { Scene *new_scene = scene_copy_no_main((Scene *)id_orig); @@ -507,7 +709,6 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph, } } if (!done) { - ID *newid; if (id_copy_no_main(id_orig, &newid)) { /* We copy contents of new ID to our CoW placeholder and free ID memory * returned by id_copy(). @@ -517,7 +718,6 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph, */ const size_t size = BKE_libblock_get_alloc_info(GS(newid->name), NULL); memcpy(id_cow, newid, size); - MEM_freeN(newid); done = true; } } @@ -531,32 +731,57 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph, #ifdef NESTED_ID_NASTY_WORKAROUND ntree_hack_remap_pointers(depsgraph, id_cow); #endif - + /* Do it now, so remapping will understand that possibly remapped self ID + * is not to be remapped again. + */ + deg_tag_copy_on_write_id(id_cow, id_orig); + /* Perform remapping of the nodes. */ + RemapCallbackUserData user_data; + user_data.depsgraph = depsgraph; + user_data.temp_id = newid; + user_data.real_id = id_cow; + user_data.node_builder = node_builder; + user_data.create_placeholders = create_placeholders; BKE_library_foreach_ID_link(NULL, id_cow, foreach_libblock_remap_callback, - (void *)depsgraph, + (void *)&user_data, IDWALK_NOP); /* Correct or tweak some pointers which are not taken care by foreach * from above. */ update_special_pointers(depsgraph, id_orig, id_cow); + /* Now we can safely discard temporary memory used for copying. */ + if (newid != NULL) { + MEM_freeN(newid); + } return id_cow; } /* NOTE: Depsgraph is supposed to have ID node already. */ -ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph, ID *id_orig) +ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph, + ID *id_orig, + DepsgraphNodeBuilder *node_builder, + bool create_placeholders) { DEG::IDDepsNode *id_node = depsgraph->find_id_node(id_orig); BLI_assert(id_node != NULL); - return deg_expand_copy_on_write_datablock(depsgraph, id_node); + return deg_expand_copy_on_write_datablock(depsgraph, + id_node, + node_builder, + create_placeholders); } ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, const IDDepsNode *id_node) { const ID *id_orig = id_node->id_orig; + const short id_type = GS(id_orig->name); ID *id_cow = id_node->id_cow; + /* Similar to expansion, no need to do anything here. */ + if (!deg_copy_on_write_is_needed(id_orig)) { + return id_cow; + } /* Special case for datablocks which are expanded at the dependency graph * construction time. This datablocks must never change pointers of their * nested data since it is used for function bindings. @@ -569,14 +794,74 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, /* For the rest if datablock types we use simple logic: * - Free previously expanded data, if any. * - Perform full datablock copy. + * + * Note that we never free GPU materials from here since that's not + * safe for threading and GPU materials are likely to be re-used. */ + ListBase gpumaterial_backup; + ListBase *gpumaterial_ptr = NULL; + Mesh *mesh_evaluated = NULL; + if (check_datablock_expanded(id_cow)) { + switch (id_type) { + case ID_MA: + { + Material *material = (Material *)id_cow; + gpumaterial_ptr = &material->gpumaterial; + break; + } + case ID_WO: + { + World *world = (World *)id_cow; + gpumaterial_ptr = &world->gpumaterial; + break; + } + case ID_OB: + { + Object *object = (Object *)id_cow; + /* Store evaluated mesh, make sure we don't free it. */ + mesh_evaluated = object->mesh_evaluated; + object->mesh_evaluated = NULL; + /* Currently object update will override actual object->data + * to an evaluated version. Need to make sure we don't have + * data set to evaluated one before free anything. + */ + if (mesh_evaluated != NULL) { + if (object->data == mesh_evaluated) { + object->data = mesh_evaluated->id.newid; + } + } + break; + } + } + if (gpumaterial_ptr != NULL) { + gpumaterial_backup = *gpumaterial_ptr; + gpumaterial_ptr->first = gpumaterial_ptr->last = NULL; + } + } deg_free_copy_on_write_datablock(id_cow); deg_expand_copy_on_write_datablock(depsgraph, id_node); + /* Restore GPU materials. */ + if (gpumaterial_ptr != NULL) { + *gpumaterial_ptr = gpumaterial_backup; + } + if (id_type == ID_OB) { + if (mesh_evaluated != NULL) { + Object *object = (Object *)id_cow; + object->mesh_evaluated = mesh_evaluated; + /* Do same thing as object update: override actual object data + * pointer with evaluated datablock. + */ + if (object->type == OB_MESH) { + object->data = mesh_evaluated; + } + } + } return id_cow; } /* NOTE: Depsgraph is supposed to have ID node already. */ -ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, ID *id_orig) +ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, + ID *id_orig) { DEG::IDDepsNode *id_node = depsgraph->find_id_node(id_orig); BLI_assert(id_node != NULL); @@ -597,6 +882,9 @@ void deg_free_copy_on_write_datablock(ID *id_cow) return; } const short type = GS(id_cow->name); +#ifdef NESTED_ID_NASTY_WORKAROUND + nested_id_hack_discard_pointers(id_cow); +#endif switch (type) { case ID_OB: { @@ -623,22 +911,20 @@ void deg_free_copy_on_write_datablock(ID *id_cow) /* Special case for scene: we use explicit function call which * ensures no access to other datablocks is done. */ - BKE_scene_free_ex((Scene *)id_cow, false); + Scene *scene = (Scene *)id_cow; + BKE_scene_free_ex(scene, false); BKE_libblock_free_data(id_cow, false); id_cow->name[0] = '\0'; return; } } -#ifdef NESTED_ID_NASTY_WORKAROUND - nested_id_hack_discard_pointers(id_cow); -#endif BKE_libblock_free_datablock(id_cow); BKE_libblock_free_data(id_cow, false); /* Signal datablock as not being expanded. */ id_cow->name[0] = '\0'; } -void deg_evaluate_copy_on_write(EvaluationContext * /*eval_ctx*/, +void deg_evaluate_copy_on_write(const EvaluationContext * /*eval_ctx*/, const Depsgraph *depsgraph, const IDDepsNode *id_node) { @@ -661,4 +947,22 @@ bool deg_validate_copy_on_write_datablock(ID *id_cow) return data.is_valid; } +void deg_tag_copy_on_write_id(ID *id_cow, const ID *id_orig) +{ + id_cow->tag |= LIB_TAG_COPY_ON_WRITE; + /* TODO(sergey): Is it safe to re-use newid for original ID link? */ + id_cow->newid = (ID *)id_orig; +} + +bool deg_copy_on_write_is_expanded(const ID *id_cow) +{ + return check_datablock_expanded(id_cow); +} + +bool deg_copy_on_write_is_needed(const ID *id_orig) +{ + const short id_type = GS(id_orig->name); + return !ELEM(id_type, ID_IM); +} + } // namespace DEG diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h index 0e1b6642002..a2b57cb7198 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h @@ -30,6 +30,8 @@ #pragma once +#include <stddef.h> + struct EvaluationContext; struct ID; @@ -48,20 +50,25 @@ struct ID; namespace DEG { struct Depsgraph; +struct DepsgraphNodeBuilder; struct IDDepsNode; /* Get fully expanded (ready for use) copy-on-write datablock for the given * original datablock. */ -ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph, - const IDDepsNode *id_node); ID *deg_expand_copy_on_write_datablock(const struct Depsgraph *depsgraph, - struct ID *id_orig); + const IDDepsNode *id_node, + DepsgraphNodeBuilder *node_builder = NULL, + bool create_placeholders = false); +ID *deg_expand_copy_on_write_datablock(const struct Depsgraph *depsgraph, + struct ID *id_orig, + DepsgraphNodeBuilder *node_builder = NULL, + bool create_placeholders = false); /* Makes sure given CoW datablock is brought back to state of the original * datablock. */ -ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, +ID *deg_update_copy_on_write_datablock(const struct Depsgraph *depsgraph, const IDDepsNode *id_node); ID *deg_update_copy_on_write_datablock(const struct Depsgraph *depsgraph, struct ID *id_orig); @@ -72,7 +79,7 @@ void deg_free_copy_on_write_datablock(struct ID *id_cow); /* Callback function for depsgraph operation node which ensures copy-on-write * datablock is ready for use by further evaluation routines. */ -void deg_evaluate_copy_on_write(struct EvaluationContext *eval_ctx, +void deg_evaluate_copy_on_write(const struct EvaluationContext *eval_ctx, const struct Depsgraph *depsgraph, const struct IDDepsNode *id_node); @@ -81,4 +88,22 @@ void deg_evaluate_copy_on_write(struct EvaluationContext *eval_ctx, */ bool deg_validate_copy_on_write_datablock(ID *id_cow); +/* Tag given ID block as being copy-on-wtritten. */ +void deg_tag_copy_on_write_id(struct ID *id_cow, const struct ID *id_orig); + +/* Check whether ID datablock is expanded. + * + * TODO(sergey): Make it an inline function or a macro. + */ +bool deg_copy_on_write_is_expanded(const struct ID *id_cow); + +/* Check whether copy-on-write datablock is needed for given ID. + * + * There are some exceptions on datablocks which are covered by dependency graph + * but which we don't want to start duplicating. + * + * This includes images. + */ +bool deg_copy_on_write_is_needed(const ID *id_orig); + } // namespace DEG diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index 605ca990e07..861e7ec2650 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -54,23 +54,6 @@ extern "C" { namespace DEG { -namespace { - -// TODO(sergey): De-duplicate with depsgraph_tag,cc -void lib_id_recalc_tag(Main *bmain, ID *id) -{ - id->tag |= LIB_TAG_ID_RECALC; - DEG_id_type_tag(bmain, GS(id->name)); -} - -void lib_id_recalc_data_tag(Main *bmain, ID *id) -{ - id->tag |= LIB_TAG_ID_RECALC_DATA; - DEG_id_type_tag(bmain, GS(id->name)); -} - -} /* namespace */ - typedef std::deque<OperationDepsNode *> FlushQueue; static void flush_init_func(void *data_v, int i) @@ -122,10 +105,8 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) */ GSET_FOREACH_BEGIN(OperationDepsNode *, op_node, graph->entry_tags) { - if ((op_node->flag & DEPSOP_FLAG_SKIP_FLUSH) == 0) { - queue.push_back(op_node); - op_node->scheduled = true; - } + queue.push_back(op_node); + op_node->scheduled = true; } GSET_FOREACH_END(); @@ -169,6 +150,14 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) } } foreach (OperationDepsNode *op, comp_node->operations) { + /* We don't want to flush tags in "upstream" direction for + * certain types of operations. + * + * TODO(sergey): Need a more generic solution for this. + */ + if (op->opcode == DEG_OPCODE_PARTICLE_SETTINGS_EVAL) { + continue; + } op->flag |= DEPSOP_FLAG_NEEDS_UPDATE; } if (object != NULL) { diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc index 07aae7e15c4..cc305665594 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node.cc @@ -128,8 +128,8 @@ IDDepsNode::ComponentIDKey::ComponentIDKey(eDepsNode_Type type, bool IDDepsNode::ComponentIDKey::operator== (const ComponentIDKey &other) const { - return type == other.type && - STREQ(name, other.name); + return type == other.type && + STREQ(name, other.name); } static unsigned int id_deps_node_hash_key(const void *key_v) @@ -165,23 +165,41 @@ static void id_deps_node_hash_value_free(void *value_v) /* Initialize 'id' node - from pointer data given. */ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata)) { - /* Store ID-pointer. */ BLI_assert(id != NULL); - this->id_orig = (ID *)id; - this->eval_flags = 0; + /* Store ID-pointer. */ + id_orig = (ID *)id; + eval_flags = 0; components = BLI_ghash_new(id_deps_node_hash_key, id_deps_node_hash_key_cmp, "Depsgraph id components hash"); +} +void IDDepsNode::init_copy_on_write(ID *id_cow_hint) +{ #ifdef WITH_COPY_ON_WRITE /* Create pointer as early as possible, so we can use it for function * bindings. Rest of data we'll be copying to the new datablock when * it is actually needed. */ - id_cow = (ID *)BKE_libblock_alloc_notest(GS(id->name)); - DEG_COW_PRINT("Create shallow copy for %s: id_orig=%p id_cow=%p\n", - id_orig->name, id_orig, id_cow); + if (id_cow_hint != NULL) { + // BLI_assert(deg_copy_on_write_is_needed(id_orig)); + if (deg_copy_on_write_is_needed(id_orig)) { + id_cow = id_cow_hint; + } + else { + id_cow = id_orig; + } + } + else if (deg_copy_on_write_is_needed(id_orig)) { + id_cow = (ID *)BKE_libblock_alloc_notest(GS(id_orig->name)); + DEG_COW_PRINT("Create shallow copy for %s: id_orig=%p id_cow=%p\n", + id_orig->name, id_orig, id_cow); + deg_tag_copy_on_write_id(id_cow, id_orig); + } + else { + id_cow = id_orig; + } #else id_cow = id_orig; #endif @@ -190,17 +208,30 @@ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata)) /* Free 'id' node. */ IDDepsNode::~IDDepsNode() { + destroy(); +} + +void IDDepsNode::destroy() +{ + if (id_orig == NULL) { + return; + } + BLI_ghash_free(components, id_deps_node_hash_key_free, id_deps_node_hash_value_free); #ifdef WITH_COPY_ON_WRITE /* Free memory used by this CoW ID. */ - deg_free_copy_on_write_datablock(id_cow); - MEM_freeN(id_cow); - DEG_COW_PRINT("Destroy CoW for %s: id_orig=%p id_cow=%p\n", - id_orig->name, id_orig, id_cow); + if (id_cow != id_orig && id_cow != NULL) { + deg_free_copy_on_write_datablock(id_cow); + MEM_freeN(id_cow); + DEG_COW_PRINT("Destroy CoW for %s: id_orig=%p id_cow=%p\n", + id_orig->name, id_orig, id_cow); + } #endif + /* Tag that the node is freed. */ + id_orig = NULL; } ComponentDepsNode *IDDepsNode::find_component(eDepsNode_Type type, @@ -243,10 +274,16 @@ void IDDepsNode::tag_update(Depsgraph *graph) /* TODO(sergey): For until we properly handle granular flags for DEG_id_tag_update() * we skip flushing here to keep Luca happy. */ - if (GS(id_orig->name) != ID_MA) { + if (GS(id_orig->name) != ID_MA && + GS(id_orig->name) != ID_WO) + { do_component_tag = false; } } + else if (comp_node->type == DEG_NODE_TYPE_EVAL_PARTICLES) { + /* Only do explicit particle settings tagging. */ + do_component_tag = false; + } if (do_component_tag) { comp_node->tag_update(graph); } diff --git a/source/blender/depsgraph/intern/nodes/deg_node.h b/source/blender/depsgraph/intern/nodes/deg_node.h index 4e03072d486..16e75b2b5e7 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.h +++ b/source/blender/depsgraph/intern/nodes/deg_node.h @@ -138,7 +138,9 @@ struct IDDepsNode : public DepsNode { }; void init(const ID *id, const char *subdata); + void init_copy_on_write(ID *id_cow_hint = NULL); ~IDDepsNode(); + void destroy(); ComponentDepsNode *find_component(eDepsNode_Type type, const char *name = "") const; diff --git a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc index 84b3d33f494..7467264f612 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc @@ -76,9 +76,6 @@ string OperationDepsNode::full_identifier() const void OperationDepsNode::tag_update(Depsgraph *graph) { - if (flag & DEPSOP_FLAG_SKIP_FLUSH) { - flag &= ~DEPSOP_FLAG_SKIP_FLUSH; - } if (flag & DEPSOP_FLAG_NEEDS_UPDATE) { return; } diff --git a/source/blender/depsgraph/intern/nodes/deg_node_operation.h b/source/blender/depsgraph/intern/nodes/deg_node_operation.h index 8a1fadd9c6c..d8203540fc5 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_operation.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_operation.h @@ -45,16 +45,6 @@ typedef enum eDepsOperation_Flag { /* node was directly modified, causing need for update */ DEPSOP_FLAG_DIRECTLY_MODIFIED = (1 << 1), - - /* Operation is evaluated using CPython; has GIL and security - * implications... - */ - DEPSOP_FLAG_USES_PYTHON = (1 << 2), - - /* Special flag which indicates that update tag sohuld not be flushed - * up to the dependent nodes. - */ - DEPSOP_FLAG_SKIP_FLUSH = (1 << 3), } eDepsOperation_Flag; /* Atomic Operation - Base type for all operations */ diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 1fada0e6f93..c6b07c76d83 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -65,6 +65,7 @@ set(SRC intern/draw_hair.c intern/draw_manager.c intern/draw_manager_text.c + intern/draw_manager_profiling.c intern/draw_view.c modes/edit_armature_mode.c modes/edit_curve_mode.c @@ -97,6 +98,7 @@ set(SRC intern/draw_cache_impl.h intern/draw_common.h intern/draw_manager_text.h + intern/draw_manager_profiling.h intern/draw_view.h modes/draw_mode_engines.h engines/basic/basic_engine.h @@ -142,7 +144,9 @@ data_to_c_simple(engines/eevee/shaders/effect_bloom_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_geom.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_downsample_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_ssr_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl SRC) data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl SRC) @@ -160,6 +164,7 @@ data_to_c_simple(engines/eevee/shaders/bsdf_common_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/irradiance_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/octahedron_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/bsdf_sampling_lib.glsl SRC) +data_to_c_simple(engines/eevee/shaders/raytrace_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/ltc_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/volumetric_frag.glsl SRC) diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c index d1afb0b4a1e..cc78a43912e 100644 --- a/source/blender/draw/engines/basic/basic_engine.c +++ b/source/blender/draw/engines/basic/basic_engine.c @@ -206,21 +206,42 @@ static void BASIC_draw_scene(void *vedata) BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl; BASIC_FramebufferList *fbl = ((BASIC_Data *)vedata)->fbl; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + const bool is_select = DRW_state_is_select(); + + bool use_color = true; + bool use_depth = true; + bool use_depth_cull = true; + + if (is_select) { + /* Needed for depth-picking, + * for other selection types there are no need for extra passes either. */ + use_color = false; + use_depth_cull = false; + } #ifdef USE_DEPTH /* Pass 1 : Depth pre-pass */ - DRW_draw_pass(psl->depth_pass); - DRW_draw_pass(psl->depth_pass_cull); + if (use_depth) { + DRW_draw_pass(psl->depth_pass); + } + + if (use_depth_cull) { + DRW_draw_pass(psl->depth_pass_cull); + } /* Pass 2 : Duplicate depth */ - /* Unless we go for deferred shading we need this to avoid manual depth test and artifacts */ - if (DRW_state_is_fbo()) { - DRW_framebuffer_blit(dfbl->default_fb, fbl->dupli_depth, true); + if (use_depth || use_depth_cull) { + /* Unless we go for deferred shading we need this to avoid manual depth test and artifacts */ + if (DRW_state_is_fbo()) { + DRW_framebuffer_blit(dfbl->default_fb, fbl->dupli_depth, true); + } } #endif /* Pass 3 : Shading */ - DRW_draw_pass(psl->color_pass); + if (use_color) { + DRW_draw_pass(psl->color_pass); + } } static void BASIC_engine_free(void) diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c index d92f0e6aad2..a9192a30412 100644 --- a/source/blender/draw/engines/clay/clay_engine.c +++ b/source/blender/draw/engines/clay/clay_engine.c @@ -40,9 +40,10 @@ #include "UI_interface_icons.h" #include "clay_engine.h" -#include "../eevee/eevee_lut.h" /* TODO find somewhere to share blue noise Table */ #ifdef WITH_CLAY_ENGINE +#include "../eevee/eevee_lut.h" /* TODO find somewhere to share blue noise Table */ + /* Shaders */ #define CLAY_ENGINE "BLENDER_CLAY" diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 861d862657e..7592e5c08d9 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -34,25 +34,47 @@ #include "DNA_view3d_types.h" #include "DNA_world_types.h" +#include "BKE_global.h" /* for G.debug_value */ #include "BKE_camera.h" #include "BKE_object.h" #include "BKE_animsys.h" #include "BKE_screen.h" +#include "DEG_depsgraph.h" + #include "BLI_dynstr.h" #include "eevee_private.h" #include "GPU_texture.h" +#include "GPU_framebuffer.h" + +#define SHADER_DEFINES \ + "#define EEVEE_ENGINE\n" \ + "#define MAX_PROBE " STRINGIFY(MAX_PROBE) "\n" \ + "#define MAX_GRID " STRINGIFY(MAX_GRID) "\n" \ + "#define MAX_PLANAR " STRINGIFY(MAX_PLANAR) "\n" typedef struct EEVEE_LightProbeData { short probe_id, shadow_id; } EEVEE_LightProbeData; +/* SSR shader variations */ +enum { + SSR_RESOLVE = (1 << 0), + SSR_FULL_TRACE = (1 << 1), + SSR_MAX_SHADER = (1 << 2), +}; + static struct { /* Downsample Depth */ - struct GPUShader *minmaxz_downlevel_sh; - struct GPUShader *minmaxz_downdepth_sh; - struct GPUShader *minmaxz_copydepth_sh; + struct GPUShader *minz_downlevel_sh; + struct GPUShader *maxz_downlevel_sh; + struct GPUShader *minz_downdepth_sh; + struct GPUShader *maxz_downdepth_sh; + struct GPUShader *minz_downdepth_layer_sh; + struct GPUShader *maxz_downdepth_layer_sh; + struct GPUShader *minz_copydepth_sh; + struct GPUShader *maxz_copydepth_sh; /* Motion Blur */ struct GPUShader *motion_blur_sh; @@ -71,21 +93,37 @@ static struct { /* Volumetric */ struct GPUShader *volumetric_upsample_sh; + /* Screen Space Reflection */ + struct GPUShader *ssr_sh[SSR_MAX_SHADER]; + + /* Simple Downsample */ + struct GPUShader *downsample_sh; + struct GPUTexture *depth_src; + struct GPUTexture *color_src; + int depth_src_layer; } e_data = {NULL}; /* Engine data */ +extern char datatoc_bsdf_common_lib_glsl[]; +extern char datatoc_bsdf_sampling_lib_glsl[]; +extern char datatoc_octahedron_lib_glsl[]; +extern char datatoc_effect_ssr_frag_glsl[]; extern char datatoc_effect_minmaxz_frag_glsl[]; extern char datatoc_effect_motion_blur_frag_glsl[]; extern char datatoc_effect_bloom_frag_glsl[]; extern char datatoc_effect_dof_vert_glsl[]; extern char datatoc_effect_dof_geom_glsl[]; extern char datatoc_effect_dof_frag_glsl[]; +extern char datatoc_effect_downsample_frag_glsl[]; +extern char datatoc_lightprobe_lib_glsl[]; +extern char datatoc_raytrace_lib_glsl[]; extern char datatoc_tonemap_frag_glsl[]; extern char datatoc_volumetric_frag_glsl[]; static void eevee_motion_blur_camera_get_matrix_at_time( - Scene *scene, ARegion *ar, RegionView3D *rv3d, View3D *v3d, Object *camera, float time, float r_mat[4][4]) + const bContext *C, Scene *scene, ARegion *ar, RegionView3D *rv3d, View3D *v3d, Object *camera, float time, float r_mat[4][4]) { + EvaluationContext eval_ctx; float obmat[4][4]; /* HACK */ @@ -94,12 +132,14 @@ static void eevee_motion_blur_camera_get_matrix_at_time( memcpy(&camdata_cpy, camera->data, sizeof(camdata_cpy)); cam_cpy.data = &camdata_cpy; + CTX_data_eval_ctx(C, &eval_ctx); + /* Past matrix */ /* FIXME : This is a temporal solution that does not take care of parent animations */ /* Recalc Anim manualy */ BKE_animsys_evaluate_animdata(scene, &cam_cpy.id, cam_cpy.adt, time, ADT_RECALC_ALL); BKE_animsys_evaluate_animdata(scene, &camdata_cpy.id, camdata_cpy.adt, time, ADT_RECALC_ALL); - BKE_object_where_is_calc_time(scene, &cam_cpy, time); + BKE_object_where_is_calc_time(&eval_ctx, scene, &cam_cpy, time); /* Compute winmat */ CameraParams params; @@ -134,6 +174,42 @@ static void eevee_motion_blur_camera_get_matrix_at_time( mul_m4_m4m4(r_mat, params.winmat, obmat); } +static struct GPUShader *eevee_effects_ssr_shader_get(int options) +{ + if (e_data.ssr_sh[options] == NULL) { + DynStr *ds_frag = BLI_dynstr_new(); + BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl); + BLI_dynstr_append(ds_frag, datatoc_bsdf_sampling_lib_glsl); + BLI_dynstr_append(ds_frag, datatoc_octahedron_lib_glsl); + BLI_dynstr_append(ds_frag, datatoc_lightprobe_lib_glsl); + BLI_dynstr_append(ds_frag, datatoc_raytrace_lib_glsl); + BLI_dynstr_append(ds_frag, datatoc_effect_ssr_frag_glsl); + char *ssr_shader_str = BLI_dynstr_get_cstring(ds_frag); + BLI_dynstr_free(ds_frag); + + DynStr *ds_defines = BLI_dynstr_new(); + BLI_dynstr_appendf(ds_defines, SHADER_DEFINES); + if (options & SSR_RESOLVE) { + BLI_dynstr_appendf(ds_defines, "#define STEP_RESOLVE\n"); + } + else { + BLI_dynstr_appendf(ds_defines, "#define STEP_RAYTRACE\n"); + } + if (options & SSR_FULL_TRACE) { + BLI_dynstr_appendf(ds_defines, "#define FULLRES\n"); + } + char *ssr_define_str = BLI_dynstr_get_cstring(ds_defines); + BLI_dynstr_free(ds_defines); + + e_data.ssr_sh[options] = DRW_shader_create_fullscreen(ssr_shader_str, ssr_define_str); + + MEM_freeN(ssr_shader_str); + MEM_freeN(ssr_define_str); + } + + return e_data.ssr_sh[options]; +} + void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) { EEVEE_StorageList *stl = vedata->stl; @@ -153,12 +229,28 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) /* Shaders */ if (!e_data.motion_blur_sh) { + e_data.downsample_sh = DRW_shader_create_fullscreen(datatoc_effect_downsample_frag_glsl, NULL); + e_data.volumetric_upsample_sh = DRW_shader_create_fullscreen(datatoc_volumetric_frag_glsl, "#define STEP_UPSAMPLE\n"); - e_data.minmaxz_downlevel_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, NULL); - e_data.minmaxz_downdepth_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define INPUT_DEPTH\n"); - e_data.minmaxz_copydepth_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define INPUT_DEPTH\n" - "#define COPY_DEPTH\n"); + e_data.minz_downlevel_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define MIN_PASS\n"); + e_data.maxz_downlevel_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define MAX_PASS\n"); + e_data.minz_downdepth_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define MIN_PASS\n" + "#define INPUT_DEPTH\n"); + e_data.maxz_downdepth_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define MAX_PASS\n" + "#define INPUT_DEPTH\n"); + e_data.minz_downdepth_layer_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define MIN_PASS\n" + "#define LAYERED\n" + "#define INPUT_DEPTH\n"); + e_data.maxz_downdepth_layer_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define MAX_PASS\n" + "#define LAYERED\n" + "#define INPUT_DEPTH\n"); + e_data.minz_copydepth_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define MIN_PASS\n" + "#define INPUT_DEPTH\n" + "#define COPY_DEPTH\n"); + e_data.maxz_copydepth_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define MAX_PASS\n" + "#define INPUT_DEPTH\n" + "#define COPY_DEPTH\n"); e_data.motion_blur_sh = DRW_shader_create_fullscreen(datatoc_effect_motion_blur_frag_glsl, NULL); @@ -194,7 +286,7 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) int enabled_effects = 0; - if (BKE_collection_engine_property_value_get_bool(props, "motion_blur_enable")) { + if (BKE_collection_engine_property_value_get_bool(props, "motion_blur_enable") && (draw_ctx->evil_C != NULL)) { /* Update Motion Blur Matrices */ if (rv3d->persp == RV3D_CAMOB && v3d->camera) { float persmat[4][4]; @@ -202,7 +294,7 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) float delta = BKE_collection_engine_property_value_get_float(props, "motion_blur_shutter"); /* Current matrix */ - eevee_motion_blur_camera_get_matrix_at_time(scene, ar, rv3d, v3d, v3d->camera, ctime, effects->current_ndc_to_world); + eevee_motion_blur_camera_get_matrix_at_time(draw_ctx->evil_C, scene, ar, rv3d, v3d, v3d->camera, ctime, effects->current_ndc_to_world); /* Viewport Matrix */ DRW_viewport_matrix_get(persmat, DRW_MAT_PERS); @@ -211,7 +303,7 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) if (compare_m4m4(persmat, effects->current_ndc_to_world, 0.0001f)) { /* Past matrix */ - eevee_motion_blur_camera_get_matrix_at_time(scene, ar, rv3d, v3d, v3d->camera, ctime - delta, effects->past_world_to_ndc); + eevee_motion_blur_camera_get_matrix_at_time(draw_ctx->evil_C, scene, ar, rv3d, v3d, v3d->camera, ctime - delta, effects->past_world_to_ndc); #if 0 /* for future high quality blur */ /* Future matrix */ @@ -395,12 +487,16 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) } /* MinMax Pyramid */ - /* TODO reduce precision */ - DRWFboTexture tex = {&stl->g_data->minmaxz, DRW_TEX_RG_32, DRW_TEX_MIPMAP | DRW_TEX_TEMP}; + DRWFboTexture texmin = {&stl->g_data->minzbuffer, DRW_TEX_DEPTH_24, DRW_TEX_MIPMAP | DRW_TEX_TEMP}; - DRW_framebuffer_init(&fbl->minmaxz_fb, &draw_engine_eevee_type, + DRW_framebuffer_init(&fbl->downsample_fb, &draw_engine_eevee_type, (int)viewport_size[0] / 2, (int)viewport_size[1] / 2, - &tex, 1); + &texmin, 1); + + /* Cannot define 2 depth texture for one framebuffer. So allocate ourself. */ + if (txl->maxzbuffer == NULL) { + txl->maxzbuffer = DRW_texture_create_2D((int)viewport_size[0] / 2, (int)viewport_size[1] / 2, DRW_TEX_DEPTH_24, DRW_TEX_MIPMAP, NULL); + } if (BKE_collection_engine_property_value_get_bool(props, "volumetric_enable")) { World *wo = scene->world; @@ -473,6 +569,88 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) } } } + + if (BKE_collection_engine_property_value_get_bool(props, "ssr_enable")) { + effects->enabled_effects |= EFFECT_SSR; + + /* Enable double buffering to be able to read previous frame color */ + effects->enabled_effects |= EFFECT_DOUBLE_BUFFER; + + effects->ssr_ray_count = BKE_collection_engine_property_value_get_int(props, "ssr_ray_count"); + effects->reflection_trace_full = !BKE_collection_engine_property_value_get_bool(props, "ssr_halfres"); + effects->ssr_use_normalization = BKE_collection_engine_property_value_get_bool(props, "ssr_normalize_weight"); + effects->ssr_quality = 1.0f - BKE_collection_engine_property_value_get_float(props, "ssr_quality"); + effects->ssr_thickness = BKE_collection_engine_property_value_get_float(props, "ssr_thickness"); + effects->ssr_border_fac = BKE_collection_engine_property_value_get_float(props, "ssr_border_fade"); + effects->ssr_firefly_fac = BKE_collection_engine_property_value_get_float(props, "ssr_firefly_fac"); + effects->ssr_max_roughness = BKE_collection_engine_property_value_get_float(props, "ssr_max_roughness"); + + if (effects->ssr_firefly_fac < 1e-8f) { + effects->ssr_firefly_fac = FLT_MAX; + } + + /* Important, can lead to breakage otherwise. */ + CLAMP(effects->ssr_ray_count, 1, 4); + + const int divisor = (effects->reflection_trace_full) ? 1 : 2; + int tracing_res[2] = {(int)viewport_size[0] / divisor, (int)viewport_size[1] / divisor}; + const bool high_qual_input = true; /* TODO dither low quality input */ + + /* MRT for the shading pass in order to output needed data for the SSR pass. */ + /* TODO create one texture layer per lobe */ + if (txl->ssr_normal_input == NULL) { + DRWTextureFormat nor_format = DRW_TEX_RG_16; + txl->ssr_normal_input = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], nor_format, 0, NULL); + } + + if (txl->ssr_specrough_input == NULL) { + DRWTextureFormat specrough_format = (high_qual_input) ? DRW_TEX_RGBA_16 : DRW_TEX_RGBA_8; + txl->ssr_specrough_input = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], specrough_format, 0, NULL); + } + + /* Reattach textures to the right buffer (because we are alternating between buffers) */ + /* TODO multiple FBO per texture!!!! */ + DRW_framebuffer_texture_detach(txl->ssr_normal_input); + DRW_framebuffer_texture_detach(txl->ssr_specrough_input); + DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0); + DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0); + + /* Raytracing output */ + /* TODO try integer format for hit coord to increase precision */ + DRWFboTexture tex_output[4] = {{&stl->g_data->ssr_hit_output[0], DRW_TEX_RGBA_16, DRW_TEX_TEMP}, + {&stl->g_data->ssr_hit_output[1], DRW_TEX_RGBA_16, DRW_TEX_TEMP}, + {&stl->g_data->ssr_hit_output[2], DRW_TEX_RGBA_16, DRW_TEX_TEMP}, + {&stl->g_data->ssr_hit_output[3], DRW_TEX_RGBA_16, DRW_TEX_TEMP}}; + + DRW_framebuffer_init(&fbl->screen_tracing_fb, &draw_engine_eevee_type, tracing_res[0], tracing_res[1], tex_output, effects->ssr_ray_count); + + /* Compute pixel size */ + copy_v2_v2(effects->ssr_pixelsize, viewport_size); + invert_v2(effects->ssr_pixelsize); + } + else { + /* Cleanup to release memory */ + DRW_TEXTURE_FREE_SAFE(txl->ssr_normal_input); + DRW_TEXTURE_FREE_SAFE(txl->ssr_specrough_input); + DRW_FRAMEBUFFER_FREE_SAFE(fbl->screen_tracing_fb); + for (int i = 0; i < 4; ++i) { + stl->g_data->ssr_hit_output[i] = NULL; + } + } + + /* Setup double buffer so we can access last frame as it was before post processes */ + if ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0) { + DRWFboTexture tex_double_buffer = {&txl->color_double_buffer, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP}; + + DRW_framebuffer_init(&fbl->double_buffer, &draw_engine_eevee_type, + (int)viewport_size[0], (int)viewport_size[1], + &tex_double_buffer, 1); + } + else { + /* Cleanup to release memory */ + DRW_TEXTURE_FREE_SAFE(txl->color_double_buffer); + DRW_FRAMEBUFFER_FREE_SAFE(fbl->double_buffer); + } } static DRWShadingGroup *eevee_create_bloom_pass(const char *name, EEVEE_EffectsInfo *effects, struct GPUShader *sh, DRWPass **pass, bool upsample) @@ -561,19 +739,107 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) } } + if ((effects->enabled_effects & EFFECT_SSR) != 0) { + int options = (effects->reflection_trace_full) ? SSR_FULL_TRACE : 0; + + struct GPUShader *trace_shader = eevee_effects_ssr_shader_get(options); + struct GPUShader *resolve_shader = eevee_effects_ssr_shader_get(SSR_RESOLVE | options); + + psl->ssr_raytrace = DRW_pass_create("SSR Raytrace", DRW_STATE_WRITE_COLOR); + DRWShadingGroup *grp = DRW_shgroup_create(trace_shader, psl->ssr_raytrace); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src); + DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input); + DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input); + DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); + DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer); + DRW_shgroup_uniform_buffer(grp, "minzBuffer", &stl->g_data->minzbuffer); + DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2); + DRW_shgroup_uniform_vec4(grp, "ssrParameters", &effects->ssr_quality, 1); + DRW_shgroup_uniform_int(grp, "rayCount", &effects->ssr_ray_count, 1); + DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1); + DRW_shgroup_uniform_float(grp, "maxRoughness", &effects->ssr_max_roughness, 1); + DRW_shgroup_uniform_buffer(grp, "planarDepth", &vedata->txl->planar_depth); + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_call_add(grp, quad, NULL); + + psl->ssr_resolve = DRW_pass_create("SSR Resolve", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE); + grp = DRW_shgroup_create(resolve_shader, psl->ssr_resolve); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src); + DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input); + DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input); + DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); + DRW_shgroup_uniform_buffer(grp, "colorBuffer", &txl->color_double_buffer); + DRW_shgroup_uniform_mat4(grp, "PastViewProjectionMatrix", (float *)stl->g_data->prev_persmat); + DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2); + DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1); + DRW_shgroup_uniform_int(grp, "probe_count", &sldata->probes->num_render_cube, 1); + DRW_shgroup_uniform_float(grp, "borderFadeFactor", &effects->ssr_border_fac, 1); + DRW_shgroup_uniform_float(grp, "maxRoughness", &effects->ssr_max_roughness, 1); + DRW_shgroup_uniform_float(grp, "lodCubeMax", &sldata->probes->lod_cube_max, 1); + DRW_shgroup_uniform_float(grp, "lodPlanarMax", &sldata->probes->lod_planar_max, 1); + DRW_shgroup_uniform_float(grp, "fireflyFactor", &effects->ssr_firefly_fac, 1); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_buffer(grp, "probeCubes", &sldata->probe_pool); + DRW_shgroup_uniform_buffer(grp, "probePlanars", &vedata->txl->planar_pool); + DRW_shgroup_uniform_buffer(grp, "hitBuffer0", &stl->g_data->ssr_hit_output[0]); + DRW_shgroup_uniform_buffer(grp, "hitBuffer1", (effects->ssr_ray_count < 2) ? &stl->g_data->ssr_hit_output[0] : &stl->g_data->ssr_hit_output[1]); + DRW_shgroup_uniform_buffer(grp, "hitBuffer2", (effects->ssr_ray_count < 3) ? &stl->g_data->ssr_hit_output[0] : &stl->g_data->ssr_hit_output[2]); + DRW_shgroup_uniform_buffer(grp, "hitBuffer3", (effects->ssr_ray_count < 4) ? &stl->g_data->ssr_hit_output[0] : &stl->g_data->ssr_hit_output[3]); + DRW_shgroup_uniform_int(grp, "rayCount", &effects->ssr_ray_count, 1); + DRW_shgroup_call_add(grp, quad, NULL); + } + { - psl->minmaxz_downlevel = DRW_pass_create("HiZ Down Level", DRW_STATE_WRITE_COLOR); - DRWShadingGroup *grp = DRW_shgroup_create(e_data.minmaxz_downlevel_sh, psl->minmaxz_downlevel); - DRW_shgroup_uniform_buffer(grp, "depthBuffer", &stl->g_data->minmaxz); + psl->color_downsample_ps = DRW_pass_create("Downsample", DRW_STATE_WRITE_COLOR); + DRWShadingGroup *grp = DRW_shgroup_create(e_data.downsample_sh, psl->color_downsample_ps); + DRW_shgroup_uniform_buffer(grp, "source", &e_data.color_src); + DRW_shgroup_call_add(grp, quad, NULL); + } + + { + /* Perform min/max downsample */ + psl->minz_downlevel_ps = DRW_pass_create("HiZ Min Down Level", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); + DRWShadingGroup *grp = DRW_shgroup_create(e_data.minz_downlevel_sh, psl->minz_downlevel_ps); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &stl->g_data->minzbuffer); + DRW_shgroup_call_add(grp, quad, NULL); + + psl->maxz_downlevel_ps = DRW_pass_create("HiZ Max Down Level", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); + grp = DRW_shgroup_create(e_data.maxz_downlevel_sh, psl->maxz_downlevel_ps); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &txl->maxzbuffer); + DRW_shgroup_call_add(grp, quad, NULL); + + /* Copy depth buffer to halfres top level of HiZ */ + psl->minz_downdepth_ps = DRW_pass_create("HiZ Min Copy Depth Halfres", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); + grp = DRW_shgroup_create(e_data.minz_downdepth_sh, psl->minz_downdepth_ps); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src); DRW_shgroup_call_add(grp, quad, NULL); - psl->minmaxz_downdepth = DRW_pass_create("HiZ Down Depth", DRW_STATE_WRITE_COLOR); - grp = DRW_shgroup_create(e_data.minmaxz_downdepth_sh, psl->minmaxz_downdepth); + psl->maxz_downdepth_ps = DRW_pass_create("HiZ Max Copy Depth Halfres", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); + grp = DRW_shgroup_create(e_data.maxz_downdepth_sh, psl->maxz_downdepth_ps); DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src); DRW_shgroup_call_add(grp, quad, NULL); - psl->minmaxz_copydepth = DRW_pass_create("HiZ Copy Depth", DRW_STATE_WRITE_COLOR); - grp = DRW_shgroup_create(e_data.minmaxz_copydepth_sh, psl->minmaxz_copydepth); + psl->minz_downdepth_layer_ps = DRW_pass_create("HiZ Min Copy DepthLayer Halfres", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); + grp = DRW_shgroup_create(e_data.minz_downdepth_layer_sh, psl->minz_downdepth_layer_ps); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src); + DRW_shgroup_uniform_int(grp, "depthLayer", &e_data.depth_src_layer, 1); + DRW_shgroup_call_add(grp, quad, NULL); + + psl->maxz_downdepth_layer_ps = DRW_pass_create("HiZ Max Copy DepthLayer Halfres", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); + grp = DRW_shgroup_create(e_data.maxz_downdepth_layer_sh, psl->maxz_downdepth_layer_ps); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src); + DRW_shgroup_uniform_int(grp, "depthLayer", &e_data.depth_src_layer, 1); + DRW_shgroup_call_add(grp, quad, NULL); + + /* Copy depth buffer to halfres top level of HiZ */ + psl->minz_copydepth_ps = DRW_pass_create("HiZ Min Copy Depth Fullres", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); + grp = DRW_shgroup_create(e_data.minz_copydepth_sh, psl->minz_copydepth_ps); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src); + DRW_shgroup_call_add(grp, quad, NULL); + + psl->maxz_copydepth_ps = DRW_pass_create("HiZ Max Copy Depth Fullres", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); + grp = DRW_shgroup_create(e_data.maxz_copydepth_sh, psl->maxz_copydepth_ps); DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src); DRW_shgroup_call_add(grp, quad, NULL); } @@ -678,39 +944,79 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) } } -#define SWAP_BUFFERS() { \ - if (effects->source_buffer == txl->color) { \ - effects->source_buffer = txl->color_post; \ - effects->target_buffer = fbl->main; \ - } \ - else { \ - effects->source_buffer = txl->color; \ - effects->target_buffer = fbl->effect_fb; \ - } \ -} ((void)0) +static void min_downsample_cb(void *vedata, int UNUSED(level)) +{ + EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; + DRW_draw_pass(psl->minz_downlevel_ps); +} + +static void max_downsample_cb(void *vedata, int UNUSED(level)) +{ + EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; + DRW_draw_pass(psl->maxz_downlevel_ps); +} -static void minmax_downsample_cb(void *vedata, int UNUSED(level)) +static void simple_downsample_cb(void *vedata, int UNUSED(level)) { EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; - DRW_draw_pass(psl->minmaxz_downlevel); + DRW_draw_pass(psl->color_downsample_ps); } -void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src) +void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src, int layer) { EEVEE_PassList *psl = vedata->psl; EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_StorageList *stl = vedata->stl; + EEVEE_TextureList *txl = vedata->txl; e_data.depth_src = depth_src; - /* Copy depth buffer to minmax texture top level */ - DRW_framebuffer_texture_attach(fbl->minmaxz_fb, stl->g_data->minmaxz, 0, 0); - DRW_framebuffer_bind(fbl->minmaxz_fb); - DRW_draw_pass(psl->minmaxz_downdepth); - DRW_framebuffer_texture_detach(stl->g_data->minmaxz); + DRW_stats_group_start("Min buffer"); + /* Copy depth buffer to min texture top level */ + DRW_framebuffer_texture_attach(fbl->downsample_fb, stl->g_data->minzbuffer, 0, 0); + DRW_framebuffer_bind(fbl->downsample_fb); + if (layer >= 0) { + e_data.depth_src_layer = layer; + DRW_draw_pass(psl->minz_downdepth_layer_ps); + } + else { + DRW_draw_pass(psl->minz_downdepth_ps); + } + DRW_framebuffer_texture_detach(stl->g_data->minzbuffer); + + /* Create lower levels */ + DRW_framebuffer_recursive_downsample(fbl->downsample_fb, stl->g_data->minzbuffer, 8, &min_downsample_cb, vedata); + DRW_stats_group_end(); + + DRW_stats_group_start("Max buffer"); + /* Copy depth buffer to max texture top level */ + DRW_framebuffer_texture_attach(fbl->downsample_fb, txl->maxzbuffer, 0, 0); + DRW_framebuffer_bind(fbl->downsample_fb); + if (layer >= 0) { + e_data.depth_src_layer = layer; + DRW_draw_pass(psl->maxz_downdepth_layer_ps); + } + else { + DRW_draw_pass(psl->maxz_downdepth_ps); + } + DRW_framebuffer_texture_detach(txl->maxzbuffer); + + /* Create lower levels */ + DRW_framebuffer_recursive_downsample(fbl->downsample_fb, txl->maxzbuffer, 8, &max_downsample_cb, vedata); + DRW_stats_group_end(); +} + +/** + * Simple downsampling algorithm. Reconstruct mip chain up to mip level. + **/ +void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src, GPUTexture *texture_src, int level) +{ + e_data.color_src = texture_src; + DRW_stats_group_start("Downsample buffer"); /* Create lower levels */ - DRW_framebuffer_recursive_downsample(fbl->minmaxz_fb, stl->g_data->minmaxz, 6, &minmax_downsample_cb, vedata); + DRW_framebuffer_recursive_downsample(fb_src, texture_src, level, &simple_downsample_cb, vedata); + DRW_stats_group_end(); } void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) @@ -747,9 +1053,79 @@ void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *veda if (sldata->volumetrics->use_colored_transmit) { DRW_framebuffer_texture_detach(stl->g_data->volumetric_transmit); } + + /* Rebind main buffer after attach/detach operations */ + DRW_framebuffer_bind(fbl->main); + } +} + +void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *vedata) +{ + EEVEE_PassList *psl = vedata->psl; + EEVEE_FramebufferList *fbl = vedata->fbl; + EEVEE_StorageList *stl = vedata->stl; + EEVEE_TextureList *txl = vedata->txl; + EEVEE_EffectsInfo *effects = stl->effects; + + if ((effects->enabled_effects & EFFECT_SSR) != 0) { + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + e_data.depth_src = dtxl->depth; + + for (int i = 0; i < effects->ssr_ray_count; ++i) { + DRW_framebuffer_texture_attach(fbl->screen_tracing_fb, stl->g_data->ssr_hit_output[i], i, 0); + } + DRW_framebuffer_bind(fbl->screen_tracing_fb); + + if (stl->g_data->valid_double_buffer) { + /* Raytrace. */ + DRW_draw_pass(psl->ssr_raytrace); + } + else { + float clear_col[4] = {0.0f, 0.0f, -1.0f, 0.001f}; + DRW_framebuffer_clear(true, false, false, clear_col, 0.0f); + } + + for (int i = 0; i < effects->ssr_ray_count; ++i) { + DRW_framebuffer_texture_detach(stl->g_data->ssr_hit_output[i]); + } + + EEVEE_downsample_buffer(vedata, fbl->downsample_fb, txl->color_double_buffer, 9); + + /* Resolve at fullres */ + DRW_framebuffer_texture_detach(dtxl->depth); + DRW_framebuffer_texture_detach(txl->ssr_normal_input); + DRW_framebuffer_texture_detach(txl->ssr_specrough_input); + DRW_framebuffer_bind(fbl->main); + DRW_draw_pass(psl->ssr_resolve); + + /* Restore */ + DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0); + DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0); + DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0); } } +#define SWAP_DOUBLE_BUFFERS() { \ + if (swap_double_buffer) { \ + SWAP(struct GPUFrameBuffer *, fbl->main, fbl->double_buffer); \ + SWAP(GPUTexture *, txl->color, txl->color_double_buffer); \ + swap_double_buffer = false; \ + } \ +} ((void)0) + +#define SWAP_BUFFERS() { \ + if (effects->source_buffer == txl->color) { \ + SWAP_DOUBLE_BUFFERS(); \ + effects->source_buffer = txl->color_post; \ + effects->target_buffer = fbl->main; \ + } \ + else { \ + SWAP_DOUBLE_BUFFERS(); \ + effects->source_buffer = txl->color; \ + effects->target_buffer = fbl->effect_fb; \ + } \ +} ((void)0) + void EEVEE_draw_effects(EEVEE_Data *vedata) { EEVEE_PassList *psl = vedata->psl; @@ -758,6 +1134,9 @@ void EEVEE_draw_effects(EEVEE_Data *vedata) EEVEE_StorageList *stl = vedata->stl; EEVEE_EffectsInfo *effects = stl->effects; + /* only once per frame after the first post process */ + bool swap_double_buffer = ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0); + /* Default framebuffer and texture */ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); @@ -869,15 +1248,68 @@ void EEVEE_draw_effects(EEVEE_Data *vedata) /* Tonemapping */ DRW_transform_to_display(effects->source_buffer); + + /* Debug : Ouput buffer to view. */ + if ((G.debug_value > 0) && (G.debug_value <= 5)) { + switch (G.debug_value) { + case 1: + if (stl->g_data->minzbuffer) DRW_transform_to_display(stl->g_data->minzbuffer); + break; + case 2: + if (stl->g_data->ssr_hit_output[0]) DRW_transform_to_display(stl->g_data->ssr_hit_output[0]); + break; + case 3: + if (txl->ssr_normal_input) DRW_transform_to_display(txl->ssr_normal_input); + break; + case 4: + if (txl->ssr_specrough_input) DRW_transform_to_display(txl->ssr_specrough_input); + break; + case 5: + if (txl->color_double_buffer) DRW_transform_to_display(txl->color_double_buffer); + break; + default: + break; + } + } + + /* If no post processes is enabled, buffers are still not swapped, do it now. */ + SWAP_DOUBLE_BUFFERS(); + + if (!stl->g_data->valid_double_buffer && + ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0) && + (DRW_state_is_image_render() == false)) + { + /* If history buffer is not valid request another frame. + * This fix black reflections on area resize. */ + DRW_viewport_request_redraw(); + } + + /* Record pers matrix for the next frame. */ + DRW_viewport_matrix_get(stl->g_data->prev_persmat, DRW_MAT_PERS); + + /* Update double buffer status if render mode. */ + if (DRW_state_is_image_render()) { + stl->g_data->valid_double_buffer = (txl->color_double_buffer != NULL); + } } void EEVEE_effects_free(void) { + for (int i = 0; i < SSR_MAX_SHADER; ++i) { + DRW_SHADER_FREE_SAFE(e_data.ssr_sh[i]); + } + DRW_SHADER_FREE_SAFE(e_data.downsample_sh); + DRW_SHADER_FREE_SAFE(e_data.volumetric_upsample_sh); - DRW_SHADER_FREE_SAFE(e_data.minmaxz_downlevel_sh); - DRW_SHADER_FREE_SAFE(e_data.minmaxz_downdepth_sh); - DRW_SHADER_FREE_SAFE(e_data.minmaxz_copydepth_sh); + DRW_SHADER_FREE_SAFE(e_data.minz_downlevel_sh); + DRW_SHADER_FREE_SAFE(e_data.maxz_downlevel_sh); + DRW_SHADER_FREE_SAFE(e_data.minz_downdepth_sh); + DRW_SHADER_FREE_SAFE(e_data.maxz_downdepth_sh); + DRW_SHADER_FREE_SAFE(e_data.minz_downdepth_layer_sh); + DRW_SHADER_FREE_SAFE(e_data.maxz_downdepth_layer_sh); + DRW_SHADER_FREE_SAFE(e_data.minz_copydepth_sh); + DRW_SHADER_FREE_SAFE(e_data.maxz_copydepth_sh); DRW_SHADER_FREE_SAFE(e_data.motion_blur_sh); DRW_SHADER_FREE_SAFE(e_data.dof_downsample_sh); @@ -892,4 +1324,4 @@ void EEVEE_effects_free(void) DRW_SHADER_FREE_SAFE(e_data.bloom_downsample_sh[1]); DRW_SHADER_FREE_SAFE(e_data.bloom_upsample_sh[1]); DRW_SHADER_FREE_SAFE(e_data.bloom_resolve_sh[1]); -}
\ No newline at end of file +} diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 1f178fb1302..f2af9c53aa8 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -49,18 +49,19 @@ static void EEVEE_engine_init(void *ved) EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; EEVEE_SceneLayerData *sldata = EEVEE_scene_layer_data_get(); - DRWFboTexture tex = {&txl->color, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}; - - const float *viewport_size = DRW_viewport_size_get(); - DRW_framebuffer_init(&fbl->main, &draw_engine_eevee_type, - (int)viewport_size[0], (int)viewport_size[1], - &tex, 1); - if (!stl->g_data) { /* Alloc transient pointers */ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); } stl->g_data->background_alpha = 1.0f; + stl->g_data->valid_double_buffer = (txl->color_double_buffer != NULL); + + DRWFboTexture tex = {&txl->color, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP}; + + const float *viewport_size = DRW_viewport_size_get(); + DRW_framebuffer_init(&fbl->main, &draw_engine_eevee_type, + (int)viewport_size[0], (int)viewport_size[1], + &tex, 1); EEVEE_materials_init(stl); EEVEE_lights_init(sldata); @@ -97,16 +98,31 @@ static void EEVEE_cache_populate(void *vedata, Object *ob) const bool cast_shadow = true; if (cast_shadow) { - BLI_addtail(&sldata->shadow_casters, BLI_genericNodeN(ob)); - EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(ob); - oedata->need_update = ((ob->deg_update_flag & DEG_RUNTIME_DATA_UPDATE) != 0); + if ((ob->base_flag & BASE_FROMDUPLI) != 0) { + /* TODO: Special case for dupli objects because we cannot save the object pointer. */ + } + else { + BLI_addtail(&sldata->shadow_casters, BLI_genericNodeN(ob)); + EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(ob); + oedata->need_update = ((ob->deg_update_flag & DEG_RUNTIME_DATA_UPDATE) != 0); + } } } else if (ob->type == OB_LIGHTPROBE) { - EEVEE_lightprobes_cache_add(sldata, ob); + if ((ob->base_flag & BASE_FROMDUPLI) != 0) { + /* TODO: Special case for dupli objects because we cannot save the object pointer. */ + } + else { + EEVEE_lightprobes_cache_add(sldata, ob); + } } else if (ob->type == OB_LAMP) { - EEVEE_lights_cache_add(sldata, ob); + if ((ob->base_flag & BASE_FROMDUPLI) != 0) { + /* TODO: Special case for dupli objects because we cannot save the object pointer. */ + } + else { + EEVEE_lights_cache_add(sldata, ob); + } } } @@ -128,44 +144,72 @@ static void EEVEE_draw_scene(void *vedata) /* Default framebuffer and texture */ DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - /* Refresh shadows */ - EEVEE_draw_shadows(sldata, psl); - - /* Refresh Probes */ - EEVEE_lightprobes_refresh(sldata, vedata); - - /* Attach depth to the hdr buffer and bind it */ - DRW_framebuffer_texture_detach(dtxl->depth); - DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0); - DRW_framebuffer_bind(fbl->main); - DRW_framebuffer_clear(false, true, false, NULL, 1.0f); - - DRW_draw_pass(psl->background_pass); - - /* Depth prepass */ - DRW_draw_pass(psl->depth_pass); - DRW_draw_pass(psl->depth_pass_cull); - - /* Create minmax texture */ - EEVEE_create_minmax_buffer(vedata, dtxl->depth); - - /* Restore main FB */ - DRW_framebuffer_bind(fbl->main); - - /* Shading pass */ - DRW_draw_pass(psl->probe_display); - EEVEE_draw_default_passes(psl); - DRW_draw_pass(psl->material_pass); - - /* Volumetrics */ - EEVEE_effects_do_volumetrics(sldata, vedata); - - /* Transparent */ - DRW_pass_sort_shgroup_z(psl->transparent_pass); - DRW_draw_pass(psl->transparent_pass); - - /* Post Process */ - EEVEE_draw_effects(vedata); + /* Number of iteration: needed for all temporal effect (SSR, TAA) + * when using opengl render. */ + int loop_ct = DRW_state_is_image_render() ? 4 : 1; + + while (loop_ct--) { + /* Refresh shadows */ + DRW_stats_group_start("Shadows"); + EEVEE_draw_shadows(sldata, psl); + DRW_stats_group_end(); + + /* Refresh Probes */ + DRW_stats_group_start("Probes Refresh"); + EEVEE_lightprobes_refresh(sldata, vedata); + DRW_stats_group_end(); + + /* Attach depth to the hdr buffer and bind it */ + DRW_framebuffer_texture_detach(dtxl->depth); + DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0); + DRW_framebuffer_bind(fbl->main); + DRW_framebuffer_clear(false, true, false, NULL, 1.0f); + + /* Depth prepass */ + DRW_stats_group_start("Prepass"); + DRW_draw_pass(psl->depth_pass); + DRW_draw_pass(psl->depth_pass_cull); + DRW_stats_group_end(); + + DRW_draw_pass(psl->background_pass); + + /* Create minmax texture */ + DRW_stats_group_start("Main MinMax buffer"); + EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1); + DRW_stats_group_end(); + + /* Restore main FB */ + DRW_framebuffer_bind(fbl->main); + + /* Shading pass */ + DRW_stats_group_start("Shading"); + EEVEE_draw_default_passes(psl); + DRW_draw_pass(psl->material_pass); + DRW_stats_group_end(); + + /* Screen Space Reflections */ + DRW_stats_group_start("SSR"); + EEVEE_effects_do_ssr(sldata, vedata); + DRW_stats_group_end(); + + DRW_draw_pass(psl->probe_display); + + /* Volumetrics */ + DRW_stats_group_start("Volumetrics"); + EEVEE_effects_do_volumetrics(sldata, vedata); + DRW_stats_group_end(); + + /* Transparent */ + DRW_pass_sort_shgroup_z(psl->transparent_pass); + DRW_stats_group_start("Transparent"); + DRW_draw_pass(psl->transparent_pass); + DRW_stats_group_end(); + + /* Post Process */ + DRW_stats_group_start("Post FX"); + EEVEE_draw_effects(vedata); + DRW_stats_group_end(); + } } static void EEVEE_engine_free(void) @@ -191,6 +235,15 @@ static void EEVEE_scene_layer_settings_create(RenderEngine *UNUSED(engine), IDPr props->type == IDP_GROUP && props->subtype == IDP_GROUP_SUB_ENGINE_RENDER); + BKE_collection_engine_property_add_bool(props, "ssr_enable", false); + BKE_collection_engine_property_add_bool(props, "ssr_halfres", true); + BKE_collection_engine_property_add_int(props, "ssr_ray_count", 1); + BKE_collection_engine_property_add_float(props, "ssr_quality", 0.25f); + BKE_collection_engine_property_add_float(props, "ssr_max_roughness", 0.5f); + BKE_collection_engine_property_add_float(props, "ssr_thickness", 0.2f); + BKE_collection_engine_property_add_float(props, "ssr_border_fade", 0.075f); + BKE_collection_engine_property_add_float(props, "ssr_firefly_fac", 0.0f); + BKE_collection_engine_property_add_bool(props, "volumetric_enable", false); BKE_collection_engine_property_add_float(props, "volumetric_start", 0.1f); BKE_collection_engine_property_add_float(props, "volumetric_end", 100.0f); diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index b2c21278cdd..7a446d221fa 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -61,9 +61,10 @@ static struct { struct GPUShader *probe_cube_display_sh; struct GPUTexture *hammersley; - struct GPUTexture *planar_depth; struct GPUTexture *planar_minmaxz; struct GPUTexture *planar_pool_placeholder; + struct GPUTexture *depth_placeholder; + struct GPUTexture *depth_array_placeholder; struct GPUTexture *cube_face_depth; struct GPUTexture *cube_face_minmaxz; @@ -147,11 +148,14 @@ static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref) if (!txl->planar_pool) { if (num_planar_ref > 0) { txl->planar_pool = DRW_texture_create_2D_array(width, height, max_ff(1, num_planar_ref), - DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); + DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); + txl->planar_depth = DRW_texture_create_2D_array(width, height, max_ff(1, num_planar_ref), + DRW_TEX_DEPTH_24, 0, NULL); } else if (num_planar_ref == 0) { /* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still bound to shader. */ txl->planar_pool = DRW_texture_create_2D_array(1, 1, 1, DRW_TEX_RGBA_8, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); + txl->planar_depth = DRW_texture_create_2D_array(1, 1, 1, DRW_TEX_DEPTH_24, 0, NULL); } } @@ -164,11 +168,6 @@ static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref) DRWFboTexture tex_minmaxz = {&e_data.planar_minmaxz, DRW_TEX_RG_32, DRW_TEX_MIPMAP | DRW_TEX_TEMP}; DRW_framebuffer_init(&fbl->planarref_fb, &draw_engine_eevee_type, width / 2, height / 2, &tex_minmaxz, 1); - - /* Note: this is not the configuration used when rendering. */ - DRWFboTexture tex = {&e_data.planar_depth, DRW_TEX_DEPTH_24, DRW_TEX_TEMP}; - DRW_framebuffer_init(&fbl->planarref_fb, &draw_engine_eevee_type, - width, height, &tex, 1); } } @@ -277,6 +276,7 @@ void EEVEE_lightprobes_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *UNUSED(ved if (!sldata->probes) { sldata->probes = MEM_callocN(sizeof(EEVEE_LightProbesInfo), "EEVEE_LightProbesInfo"); sldata->probes->specular_toggle = true; + sldata->probes->ssr_toggle = true; sldata->probe_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightProbe) * MAX_PROBE, NULL); sldata->grid_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightGrid) * MAX_GRID, NULL); sldata->planar_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_PlanarReflection) * MAX_PLANAR, NULL); @@ -303,14 +303,20 @@ void EEVEE_lightprobes_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *UNUSED(ved } /* Minmaxz Pyramid */ - /* Highjacking the minmaxz_fb but that's ok because it's reconfigured before usage. */ // DRWFboTexture tex_minmaxz = {&e_data.cube_face_minmaxz, DRW_TEX_RG_32, DRW_TEX_MIPMAP | DRW_TEX_TEMP}; - // DRW_framebuffer_init(&vedata->fbl->minmaxz_fb, &draw_engine_eevee_type, PROBE_RT_SIZE / 2, PROBE_RT_SIZE / 2, &tex_minmaxz, 1); + // DRW_framebuffer_init(&vedata->fbl->downsample_fb, &draw_engine_eevee_type, PROBE_RT_SIZE / 2, PROBE_RT_SIZE / 2, &tex_minmaxz, 1); /* Placeholder planar pool: used when rendering planar reflections (avoid dependency loop). */ if (!e_data.planar_pool_placeholder) { e_data.planar_pool_placeholder = DRW_texture_create_2D_array(1, 1, 1, DRW_TEX_RGBA_8, DRW_TEX_FILTER, NULL); } + + if (!e_data.depth_placeholder) { + e_data.depth_placeholder = DRW_texture_create_2D(1, 1, DRW_TEX_DEPTH_24, 0, NULL); + } + if (!e_data.depth_array_placeholder) { + e_data.depth_array_placeholder = DRW_texture_create_2D_array(1, 1, 1, DRW_TEX_DEPTH_24, 0, NULL); + } } void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) @@ -328,7 +334,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *veda memset(pinfo->probes_planar_ref, 0, sizeof(pinfo->probes_planar_ref)); { - psl->probe_background = DRW_pass_create("World Probe Pass", DRW_STATE_WRITE_COLOR); + psl->probe_background = DRW_pass_create("World Probe Background Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); DRWShadingGroup *grp = NULL; @@ -724,6 +730,7 @@ void EEVEE_lightprobes_cache_finish(EEVEE_SceneLayerData *sldata, EEVEE_Data *ve if (pinfo->num_planar != pinfo->cache_num_planar) { DRW_TEXTURE_FREE_SAFE(vedata->txl->planar_pool); + DRW_TEXTURE_FREE_SAFE(vedata->txl->planar_depth); pinfo->cache_num_planar = pinfo->num_planar; } @@ -956,6 +963,7 @@ static void render_scene_to_probe( /* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */ sldata->probes->specular_toggle = false; + sldata->probes->ssr_toggle = false; /* Disable AO until we find a way to hide really bad discontinuities between cubefaces. */ tmp_ao_dist = stl->effects->ao_dist; @@ -972,9 +980,11 @@ static void render_scene_to_probe( /* Avoid using the texture attached to framebuffer when rendering. */ /* XXX */ GPUTexture *tmp_planar_pool = txl->planar_pool; - GPUTexture *tmp_minmaxz = stl->g_data->minmaxz; + GPUTexture *tmp_minz = stl->g_data->minzbuffer; + GPUTexture *tmp_maxz = txl->maxzbuffer; txl->planar_pool = e_data.planar_pool_placeholder; - // stl->g_data->minmaxz = e_data.cube_face_minmaxz; + stl->g_data->minzbuffer = e_data.depth_placeholder; + txl->maxzbuffer = e_data.depth_placeholder; /* Detach to rebind the right cubeface. */ DRW_framebuffer_bind(sldata->probe_fb); @@ -1001,12 +1011,12 @@ static void render_scene_to_probe( DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV); DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN); - DRW_draw_pass(psl->probe_background); - /* Depth prepass */ DRW_draw_pass(psl->depth_pass); DRW_draw_pass(psl->depth_pass_cull); + DRW_draw_pass(psl->probe_background); + // EEVEE_create_minmax_buffer(vedata, e_data.cube_face_depth); /* Rebind Planar FB */ @@ -1030,20 +1040,20 @@ static void render_scene_to_probe( /* Restore */ sldata->probes->specular_toggle = true; txl->planar_pool = tmp_planar_pool; - stl->g_data->minmaxz = tmp_minmaxz; + stl->g_data->minzbuffer = tmp_minz; + txl->maxzbuffer = tmp_maxz; stl->effects->ao_dist = tmp_ao_dist; stl->effects->ao_samples = tmp_ao_samples; } static void render_scene_to_planar( - EEVEE_Data *vedata, int layer, + EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, int layer, float (*viewmat)[4], float (*persmat)[4], float clip_plane[4]) { EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_TextureList *txl = vedata->txl; EEVEE_PassList *psl = vedata->psl; - EEVEE_StorageList *stl = vedata->stl; float viewinv[4][4]; float persinv[4][4]; @@ -1052,28 +1062,28 @@ static void render_scene_to_planar( invert_m4_m4(persinv, persmat); /* Attach depth here since it's a DRW_TEX_TEMP */ - DRW_framebuffer_texture_attach(fbl->planarref_fb, e_data.planar_depth, 0, 0); + DRW_framebuffer_texture_layer_attach(fbl->planarref_fb, txl->planar_depth, 0, layer, 0); DRW_framebuffer_texture_layer_attach(fbl->planarref_fb, txl->planar_pool, 0, layer, 0); DRW_framebuffer_bind(fbl->planarref_fb); DRW_framebuffer_clear(false, true, false, NULL, 1.0); + /* Turn off ssr to avoid black specular */ + /* TODO : Enable SSR in planar reflections? (Would be very heavy) */ + sldata->probes->ssr_toggle = false; + /* Avoid using the texture attached to framebuffer when rendering. */ /* XXX */ GPUTexture *tmp_planar_pool = txl->planar_pool; - GPUTexture *tmp_minmaxz = stl->g_data->minmaxz; + GPUTexture *tmp_planar_depth = txl->planar_depth; txl->planar_pool = e_data.planar_pool_placeholder; - stl->g_data->minmaxz = e_data.planar_minmaxz; - stl->g_data->background_alpha = FLT_MAX; /* Alpha is distance for planar reflections. */ + txl->planar_depth = e_data.depth_array_placeholder; DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS); DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV); DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW); DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV); - /* Background */ - DRW_draw_pass(psl->probe_background); - /* Since we are rendering with an inverted view matrix, we need * to invert the facing for backface culling to be the same. */ DRW_state_invert_facing(); @@ -1083,7 +1093,10 @@ static void render_scene_to_planar( DRW_draw_pass(psl->depth_pass_clip); DRW_draw_pass(psl->depth_pass_clip_cull); - EEVEE_create_minmax_buffer(vedata, e_data.planar_depth); + /* Background */ + DRW_draw_pass(psl->probe_background); + + EEVEE_create_minmax_buffer(vedata, tmp_planar_depth, layer); /* Rebind Planar FB */ DRW_framebuffer_bind(fbl->planarref_fb); @@ -1096,16 +1109,16 @@ static void render_scene_to_planar( DRW_state_clip_planes_reset(); /* Restore */ + sldata->probes->ssr_toggle = true; txl->planar_pool = tmp_planar_pool; - stl->g_data->minmaxz = tmp_minmaxz; - stl->g_data->background_alpha = 1.0; + txl->planar_depth = tmp_planar_depth; DRW_viewport_matrix_override_unset(DRW_MAT_PERS); DRW_viewport_matrix_override_unset(DRW_MAT_PERSINV); DRW_viewport_matrix_override_unset(DRW_MAT_VIEW); DRW_viewport_matrix_override_unset(DRW_MAT_VIEWINV); DRW_framebuffer_texture_detach(txl->planar_pool); - DRW_framebuffer_texture_detach(e_data.planar_depth); + DRW_framebuffer_texture_detach(txl->planar_depth); } static void render_world_to_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl) @@ -1256,7 +1269,10 @@ void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) if (ped->updated_cells >= ped->num_cell) { ped->need_update = false; } - +#if 0 + printf("Updated Grid %d : cell %d / %d, bounce %d / %d\n", + i, ped->updated_cells, ped->num_cell, pinfo->updated_bounce + 1, max_bounce); +#endif /* Only do one probe per frame */ DRW_viewport_request_redraw(); goto update_planar; @@ -1293,7 +1309,9 @@ void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) pinfo->num_render_cube++; ped->ready_to_shade = true; } - +#if 0 + printf("Update Cubemap %d\n", i); +#endif DRW_viewport_request_redraw(); /* Only do one probe per frame */ @@ -1312,7 +1330,7 @@ update_planar: int tmp_num_planar = pinfo->num_planar; pinfo->num_planar = 0; - render_scene_to_planar(vedata, i, ped->viewmat, ped->persmat, ped->planer_eq_offset); + render_scene_to_planar(sldata, vedata, i, ped->viewmat, ped->persmat, ped->planer_eq_offset); /* Restore */ pinfo->num_planar = tmp_num_planar; @@ -1323,11 +1341,13 @@ update_planar: } /* If there is at least one planar probe */ - if (pinfo->num_planar > 0) { - const int max_lod = 5; - DRW_framebuffer_recursive_downsample(vedata->fbl->minmaxz_fb, txl->planar_pool, max_lod, &downsample_planar, vedata); + if (pinfo->num_planar > 0 && (vedata->stl->effects->enabled_effects & EFFECT_SSR) != 0) { + const int max_lod = 9; + DRW_stats_group_start("Planar Probe Downsample"); + DRW_framebuffer_recursive_downsample(vedata->fbl->downsample_fb, txl->planar_pool, max_lod, &downsample_planar, vedata); /* For shading, save max level of the planar map */ pinfo->lod_planar_max = (float)(max_lod); + DRW_stats_group_end(); } } @@ -1342,4 +1362,6 @@ void EEVEE_lightprobes_free(void) DRW_SHADER_FREE_SAFE(e_data.probe_cube_display_sh); DRW_TEXTURE_FREE_SAFE(e_data.hammersley); DRW_TEXTURE_FREE_SAFE(e_data.planar_pool_placeholder); + DRW_TEXTURE_FREE_SAFE(e_data.depth_placeholder); + DRW_TEXTURE_FREE_SAFE(e_data.depth_array_placeholder); } diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 9772666d3ae..e91ffeaa6b8 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -261,8 +261,15 @@ static char *eevee_get_volume_defines(int options) return str; } -static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) +/** + * ssr_id can be null to disable ssr contribution. + **/ +static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, int *ssr_id) { + if (ssr_id == NULL) { + static int no_ssr = -1.0f; + ssr_id = &no_ssr; + } DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo); DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo); DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo); @@ -273,6 +280,7 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData * DRW_shgroup_uniform_int(shgrp, "grid_count", &sldata->probes->num_render_grid, 1); DRW_shgroup_uniform_int(shgrp, "planar_count", &sldata->probes->num_planar, 1); DRW_shgroup_uniform_bool(shgrp, "specToggle", &sldata->probes->specular_toggle, 1); + DRW_shgroup_uniform_bool(shgrp, "ssrToggle", &sldata->probes->ssr_toggle, 1); DRW_shgroup_uniform_float(shgrp, "lodCubeMax", &sldata->probes->lod_cube_max, 1); DRW_shgroup_uniform_float(shgrp, "lodPlanarMax", &sldata->probes->lod_planar_max, 1); DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex); @@ -281,9 +289,10 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData * DRW_shgroup_uniform_buffer(shgrp, "irradianceGrid", &sldata->irradiance_pool); DRW_shgroup_uniform_buffer(shgrp, "shadowCubes", &sldata->shadow_depth_cube_pool); DRW_shgroup_uniform_buffer(shgrp, "shadowCascades", &sldata->shadow_depth_cascade_pool); + DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1); if (vedata->stl->effects->use_ao) { DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)&vedata->stl->g_data->viewvecs, 2); - DRW_shgroup_uniform_buffer(shgrp, "minMaxDepthTex", &vedata->stl->g_data->minmaxz); + DRW_shgroup_uniform_buffer(shgrp, "minMaxDepthTex", &vedata->txl->maxzbuffer); DRW_shgroup_uniform_vec3(shgrp, "aoParameters", &vedata->stl->effects->ao_dist, 1); } } @@ -369,8 +378,9 @@ void EEVEE_materials_init(EEVEE_StorageList *stl) BLI_dynstr_free(ds_frag); } - e_data.default_background = DRW_shader_create_fullscreen( - datatoc_default_world_frag_glsl, NULL); + e_data.default_background = DRW_shader_create( + datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl, + NULL); e_data.default_prepass_sh = DRW_shader_create( datatoc_prepass_vert_glsl, NULL, datatoc_prepass_frag_glsl, @@ -642,8 +652,10 @@ struct GPUMaterial *EEVEE_material_hair_get( **/ static struct DRWShadingGroup *EEVEE_default_shading_group_create( EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, DRWPass *pass, - bool is_hair, bool is_hair_fibers, bool is_flat_normal, bool use_ao, bool use_bent_normals, bool use_blend) + bool is_hair, bool is_hair_fibers, bool is_flat_normal, bool use_ao, bool use_bent_normals, bool use_blend, bool use_ssr) { + static int ssr_id; + ssr_id = (use_ssr) ? 0 : -1; int options = VAR_MAT_MESH; if (is_hair) options |= VAR_MAT_HAIR; @@ -658,7 +670,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create( } DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass); - add_standard_uniforms(shgrp, sldata, vedata); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id); return shgrp; } @@ -668,8 +680,10 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create( **/ static struct DRWShadingGroup *EEVEE_default_shading_group_get( EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, - bool is_hair, bool is_hair_fibers, bool is_flat_normal, bool use_ao, bool use_bent_normals) + bool is_hair, bool is_hair_fibers, bool is_flat_normal, bool use_ao, bool use_bent_normals, bool use_ssr) { + static int ssr_id; + ssr_id = (use_ssr) ? 0 : -1; int options = VAR_MAT_MESH; if (is_hair) options |= VAR_MAT_HAIR; @@ -688,7 +702,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get( vedata->psl->default_pass[options] = DRW_pass_create("Default Lit Pass", state); DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]); - add_standard_uniforms(shgrp, sldata, vedata); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id); } return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]); @@ -700,12 +714,14 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata) EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; { - /* Global AO Switch*/ const DRWContextState *draw_ctx = DRW_context_state_get(); SceneLayer *scene_layer = draw_ctx->scene_layer; IDProperty *props = BKE_scene_layer_engine_evaluated_get(scene_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE); + /* Global AO Switch*/ stl->effects->use_ao = BKE_collection_engine_property_value_get_bool(props, "gtao_enable"); stl->effects->use_bent_normals = BKE_collection_engine_property_value_get_bool(props, "gtao_use_bent_normals"); + /* SSR switch */ + stl->effects->use_ssr = BKE_collection_engine_property_value_get_bool(props, "ssr_enable"); } /* Create Material Ghash */ @@ -715,7 +731,7 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata) } { - psl->background_pass = DRW_pass_create("Background Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR); + psl->background_pass = DRW_pass_create("Background Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); DRWShadingGroup *grp = NULL; @@ -847,7 +863,9 @@ static void material_opaque( *shgrp = DRW_shgroup_material_create(*gpumat, psl->material_pass); if (*shgrp) { - add_standard_uniforms(*shgrp, sldata, vedata); + static int ssr_id; + ssr_id = (stl->effects->use_ssr) ? 0 : -1; + add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id); } else { /* Shader failed : pink color */ @@ -867,7 +885,7 @@ static void material_opaque( *shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, do_cull ? psl->depth_pass_cull : psl->depth_pass); *shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, do_cull ? psl->depth_pass_clip_cull : psl->depth_pass_clip); - if (shgrp_depth) { + if (*shgrp != NULL) { if (ma->blend_method == MA_BM_CLIP) { DRW_shgroup_uniform_float(*shgrp_depth, "alphaThreshold", &ma->alpha_threshold, 1); DRW_shgroup_uniform_float(*shgrp_depth_clip, "alphaThreshold", &ma->alpha_threshold, 1); @@ -879,7 +897,7 @@ static void material_opaque( /* Fallback to default shader */ if (*shgrp == NULL) { *shgrp = EEVEE_default_shading_group_get(sldata, vedata, false, false, use_flat_nor, - stl->effects->use_ao, stl->effects->use_bent_normals); + stl->effects->use_ao, stl->effects->use_bent_normals, stl->effects->use_ssr); DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1); DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1); DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1); @@ -921,7 +939,8 @@ static void material_transparent( *shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass); if (*shgrp) { - add_standard_uniforms(*shgrp, sldata, vedata); + static int ssr_id = -1; /* TODO transparent SSR */ + add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id); } else { /* Shader failed : pink color */ @@ -937,7 +956,7 @@ static void material_transparent( if (*shgrp == NULL) { *shgrp = EEVEE_default_shading_group_create( sldata, vedata, psl->transparent_pass, - false, false, use_flat_nor, stl->effects->use_ao, stl->effects->use_bent_normals, true); + false, false, use_flat_nor, stl->effects->use_ao, stl->effects->use_bent_normals, true, false); DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1); DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1); DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1); @@ -1187,7 +1206,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass); if (shgrp) { - add_standard_uniforms(shgrp, sldata, vedata); + add_standard_uniforms(shgrp, sldata, vedata, NULL); BLI_ghash_insert(material_hash, ma, shgrp); } @@ -1204,7 +1223,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl /* Fallback to default shader */ if (shgrp == NULL) { shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, use_fibers, - false, stl->effects->use_ao, stl->effects->use_bent_normals); + false, stl->effects->use_ao, stl->effects->use_bent_normals, stl->effects->use_ssr); DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1); DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1); DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index fdf2313d1ee..f8a506511b2 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -104,12 +104,22 @@ typedef struct EEVEE_PassList { struct DRWPass *dof_down; struct DRWPass *dof_scatter; struct DRWPass *dof_resolve; - struct DRWPass *minmaxz_downlevel; - struct DRWPass *minmaxz_downdepth; - struct DRWPass *minmaxz_copydepth; struct DRWPass *volumetric_integrate_ps; struct DRWPass *volumetric_resolve_ps; struct DRWPass *volumetric_resolve_transmit_ps; + struct DRWPass *ssr_raytrace; + struct DRWPass *ssr_resolve; + struct DRWPass *color_downsample_ps; + + /* HiZ */ + struct DRWPass *minz_downlevel_ps; + struct DRWPass *maxz_downlevel_ps; + struct DRWPass *minz_downdepth_ps; + struct DRWPass *maxz_downdepth_ps; + struct DRWPass *minz_downdepth_layer_ps; + struct DRWPass *maxz_downdepth_layer_ps; + struct DRWPass *minz_copydepth_ps; + struct DRWPass *maxz_copydepth_ps; struct DRWPass *depth_pass; struct DRWPass *depth_pass_cull; @@ -123,7 +133,7 @@ typedef struct EEVEE_PassList { typedef struct EEVEE_FramebufferList { /* Effects */ - struct GPUFrameBuffer *minmaxz_fb; + struct GPUFrameBuffer *downsample_fb; struct GPUFrameBuffer *effect_fb; struct GPUFrameBuffer *bloom_blit_fb; struct GPUFrameBuffer *bloom_down_fb[MAX_BLOOM_STEP]; @@ -132,10 +142,12 @@ typedef struct EEVEE_FramebufferList { struct GPUFrameBuffer *dof_scatter_far_fb; struct GPUFrameBuffer *dof_scatter_near_fb; struct GPUFrameBuffer *volumetric_fb; + struct GPUFrameBuffer *screen_tracing_fb; struct GPUFrameBuffer *planarref_fb; struct GPUFrameBuffer *main; + struct GPUFrameBuffer *double_buffer; } EEVEE_FramebufferList; typedef struct EEVEE_TextureList { @@ -150,9 +162,16 @@ typedef struct EEVEE_TextureList { struct GPUTexture *bloom_downsample[MAX_BLOOM_STEP]; /* R16_G16_B16 */ struct GPUTexture *bloom_upsample[MAX_BLOOM_STEP-1]; /* R16_G16_B16 */ + struct GPUTexture *ssr_normal_input; + struct GPUTexture *ssr_specrough_input; + struct GPUTexture *planar_pool; + struct GPUTexture *planar_depth; + + struct GPUTexture *maxzbuffer; struct GPUTexture *color; /* R16_G16_B16 */ + struct GPUTexture *color_double_buffer; } EEVEE_TextureList; typedef struct EEVEE_StorageList { @@ -281,6 +300,7 @@ typedef struct EEVEE_LightProbesInfo { int shres; int shnbr; bool specular_toggle; + bool ssr_toggle; /* List of probes in the scene. */ /* XXX This is fragile, can get out of sync quickly. */ struct Object *probes_cube_ref[MAX_PROBE]; @@ -301,6 +321,18 @@ enum { typedef struct EEVEE_EffectsInfo { int enabled_effects; + /* SSR */ + bool use_ssr; + bool reflection_trace_full; + bool ssr_use_normalization; + int ssr_ray_count; + float ssr_firefly_fac; + float ssr_border_fac; + float ssr_max_roughness; + float ssr_quality; + float ssr_thickness; + float ssr_pixelsize[2]; + /* Ambient Occlusion */ bool use_ao, use_bent_normals; float ao_dist, ao_samples, ao_factor; @@ -340,6 +372,8 @@ enum { EFFECT_BLOOM = (1 << 1), EFFECT_DOF = (1 << 2), EFFECT_VOLUMETRIC = (1 << 3), + EFFECT_SSR = (1 << 4), + EFFECT_DOUBLE_BUFFER = (1 << 5), /* Not really an effect but a feature */ }; /* ************** SCENE LAYER DATA ************** */ @@ -433,13 +467,17 @@ typedef struct EEVEE_PrivateData { struct DRWShadingGroup *planar_downsample; struct GHash *material_hash; struct GHash *hair_material_hash; - struct GPUTexture *minmaxz; + struct GPUTexture *minzbuffer; + struct GPUTexture *ssr_hit_output[4]; struct GPUTexture *volumetric; struct GPUTexture *volumetric_transmit; float background_alpha; /* TODO find a better place for this. */ float viewvecs[2][4]; /* For planar probes */ float texel_size[2]; + /* For double buffering */ + bool valid_double_buffer; + float prev_persmat[4][4]; } EEVEE_PrivateData; /* Transient data */ /* eevee_data.c */ @@ -489,51 +527,53 @@ void EEVEE_lightprobes_free(void); /* eevee_effects.c */ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata); void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata); -void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src); +void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src, int layer); +void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src, struct GPUTexture *texture_src, int level); void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata); void EEVEE_draw_effects(EEVEE_Data *vedata); void EEVEE_effects_free(void); /* Shadow Matrix */ static const float texcomat[4][4] = { /* From NDC to TexCo */ - {0.5, 0.0, 0.0, 0.0}, - {0.0, 0.5, 0.0, 0.0}, - {0.0, 0.0, 0.5, 0.0}, - {0.5, 0.5, 0.5, 1.0} + {0.5f, 0.0f, 0.0f, 0.0f}, + {0.0f, 0.5f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.5f, 0.0f}, + {0.5f, 0.5f, 0.5f, 1.0f} }; /* Cubemap Matrices */ static const float cubefacemat[6][4][4] = { /* Pos X */ - {{0.0, 0.0, -1.0, 0.0}, - {0.0, -1.0, 0.0, 0.0}, - {-1.0, 0.0, 0.0, 0.0}, - {0.0, 0.0, 0.0, 1.0}}, + {{0.0f, 0.0f, -1.0f, 0.0f}, + {0.0f, -1.0f, 0.0f, 0.0f}, + {-1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f}}, /* Neg X */ - {{0.0, 0.0, 1.0, 0.0}, - {0.0, -1.0, 0.0, 0.0}, - {1.0, 0.0, 0.0, 0.0}, - {0.0, 0.0, 0.0, 1.0}}, + {{0.0f, 0.0f, 1.0f, 0.0f}, + {0.0f, -1.0f, 0.0f, 0.0f}, + {1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f}}, /* Pos Y */ - {{1.0, 0.0, 0.0, 0.0}, - {0.0, 0.0, -1.0, 0.0}, - {0.0, 1.0, 0.0, 0.0}, - {0.0, 0.0, 0.0, 1.0}}, + {{1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, -1.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f}}, /* Neg Y */ - {{1.0, 0.0, 0.0, 0.0}, - {0.0, 0.0, 1.0, 0.0}, - {0.0, -1.0, 0.0, 0.0}, - {0.0, 0.0, 0.0, 1.0}}, + {{1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, + {0.0f, -1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f}}, /* Pos Z */ - {{1.0, 0.0, 0.0, 0.0}, - {0.0, -1.0, 0.0, 0.0}, - {0.0, 0.0, -1.0, 0.0}, - {0.0, 0.0, 0.0, 1.0}}, + {{1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, -1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, -1.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f}}, /* Neg Z */ - {{-1.0, 0.0, 0.0, 0.0}, - {0.0, -1.0, 0.0, 0.0}, - {0.0, 0.0, 1.0, 0.0}, - {0.0, 0.0, 0.0, 1.0}}, + {{-1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, -1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f}}, }; #endif /* __EEVEE_PRIVATE_H__ */ diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl index 77bae174985..5a59e362fba 100644 --- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl @@ -16,7 +16,7 @@ uniform vec3 aoParameters; float get_max_horizon(vec2 co, vec3 x, float h, float lod) { - float depth = textureLod(minMaxDepthTex, co, floor(lod)).g; + float depth = textureLod(minMaxDepthTex, co, floor(lod)).r; /* Background case */ /* this is really slow and is only a problem diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl index f3f9d8af7f0..e80835ee498 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -9,6 +9,7 @@ #define LUT_SIZE 64 uniform mat4 ProjectionMatrix; +uniform mat4 ViewProjectionMatrix; uniform mat4 ViewMatrixInverse; uniform vec4 viewvecs[2]; #ifndef SHADOW_SHADER @@ -28,82 +29,10 @@ flat in int shFace; /* Shadow layer we are rendering to. */ #define cameraForward normalize(ViewMatrixInverse[2].xyz) #define cameraPos ViewMatrixInverse[3].xyz - +#define cameraVec ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward) +#define viewCameraVec ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0)) /* ------- Structures -------- */ -#ifdef VOLUMETRICS - -struct Closure { - vec3 absorption; - vec3 scatter; - vec3 emission; - float anisotropy; -}; - -#define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0) - -Closure closure_mix(Closure cl1, Closure cl2, float fac) -{ - Closure cl; - cl.absorption = mix(cl1.absorption, cl2.absorption, fac); - cl.scatter = mix(cl1.scatter, cl2.scatter, fac); - cl.emission = mix(cl1.emission, cl2.emission, fac); - cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac); - return cl; -} - -Closure closure_add(Closure cl1, Closure cl2) -{ - Closure cl; - cl.absorption = cl1.absorption + cl2.absorption; - cl.scatter = cl1.scatter + cl2.scatter; - cl.emission = cl1.emission + cl2.emission; - cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */ - return cl; -} -#else - -struct Closure { - vec3 radiance; - float opacity; -}; - -#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0) - -Closure closure_mix(Closure cl1, Closure cl2, float fac) -{ - Closure cl; - cl.radiance = mix(cl1.radiance, cl2.radiance, fac); - cl.opacity = mix(cl1.opacity, cl2.opacity, fac); - return cl; -} - -Closure closure_add(Closure cl1, Closure cl2) -{ - Closure cl; - cl.radiance = cl1.radiance + cl2.radiance; - cl.opacity = cl1.opacity + cl2.opacity; - return cl; -} - -#endif /* VOLUMETRICS */ - -Closure nodetree_exec(void); /* Prototype */ - -/* TODO find a better place */ -#ifdef USE_MULTIPLY - -out vec4 fragColor; - -#define NODETREE_EXEC -void main() -{ - Closure cl = nodetree_exec(); - fragColor = vec4(mix(vec3(1.0), cl.radiance, cl.opacity), 1.0); -} - -#endif - struct LightData { vec4 position_influence; /* w : InfluenceRadius */ vec4 color_spec; /* w : Spec Intensity */ @@ -162,15 +91,19 @@ struct ShadowCascadeData { vec4 bias; }; -#define cameraVec ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward) - /* ------- Convenience functions --------- */ vec3 mul(mat3 m, vec3 v) { return m * v; } mat3 mul(mat3 m1, mat3 m2) { return m1 * m2; } +vec3 transform_direction(mat4 m, vec3 v) { return mat3(m) * v; } vec3 transform_point(mat4 m, vec3 v) { return (m * vec4(v, 1.0)).xyz; } +vec3 project_point(mat4 m, vec3 v) { + vec4 tmp = m * vec4(v, 1.0); + return tmp.xyz / tmp.w; +} float min_v3(vec3 v) { return min(v.x, min(v.y, v.z)); } +float max_v2(vec2 v) { return max(v.x, v.y); } float saturate(float a) { return clamp(a, 0.0, 1.0); } vec2 saturate(vec2 a) { return clamp(a, 0.0, 1.0); } @@ -199,6 +132,11 @@ float fast_acos(float x) return (x >= 0) ? res : M_PI - res; } +float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal) +{ + return dot(planenormal, planeorigin - lineorigin); +} + float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal) { return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection); @@ -217,6 +155,12 @@ vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, return lineorigin + linedirection * dist; } +vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane) +{ + float dist = line_plane_intersect_dist(lineorigin, linedirection, plane); + return lineorigin + linedirection * dist; +} + float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) { /* aligned plane normal */ @@ -332,6 +276,11 @@ vec3 get_view_space_from_depth(vec2 uvcoords, float depth) } } +vec3 get_world_space_from_depth(vec2 uvcoords, float depth) +{ + return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz; +} + vec3 get_specular_dominant_dir(vec3 N, vec3 V, float roughness) { vec3 R = -reflect(V, N); @@ -345,6 +294,26 @@ float specular_occlusion(float NV, float AO, float roughness) return saturate(pow(NV + AO, roughness) - 1.0 + AO); } +/* ---- Encode / Decode Normal buffer data ---- */ +/* From http://aras-p.info/texts/CompactNormalStorage.html + * Using Method #4: Spheremap Transform */ +vec2 normal_encode(vec3 n, vec3 view) +{ + float p = sqrt(n.z * 8.0 + 8.0); + return n.xy / p + 0.5; +} + +vec3 normal_decode(vec2 enc, vec3 view) +{ + vec2 fenc = enc * 4.0 - 2.0; + float f = dot(fenc, fenc); + float g = sqrt(1.0 - f / 4.0); + vec3 n; + n.xy = fenc*g; + n.z = 1 - f / 2; + return n; +} + /* Fresnel */ vec3 F_schlick(vec3 f0, float cos_theta) { @@ -411,4 +380,126 @@ float bsdf_ggx(vec3 N, vec3 L, vec3 V, float roughness) void accumulate_light(vec3 light, float fac, inout vec4 accum) { accum += vec4(light, 1.0) * min(fac, (1.0 - accum.a)); -}
\ No newline at end of file +} + +/* ----------- Cone Apperture Approximation --------- */ + +/* Return a fitted cone angle given the input roughness */ +float cone_cosine(float r) +{ + /* Using phong gloss + * roughness = sqrt(2/(gloss+2)) */ + float gloss = -2 + 2 / (r * r); + /* Drobot 2014 in GPUPro5 */ + // return cos(2.0 * sqrt(2.0 / (gloss + 2))); + /* Uludag 2014 in GPUPro5 */ + // return pow(0.244, 1 / (gloss + 1)); + /* Jimenez 2016 in Practical Realtime Strategies for Accurate Indirect Occlusion*/ + return exp2(-3.32193 * r * r); +} + +/* --------- Closure ---------- */ +#ifdef VOLUMETRICS + +struct Closure { + vec3 absorption; + vec3 scatter; + vec3 emission; + float anisotropy; +}; + +#define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0) + +Closure closure_mix(Closure cl1, Closure cl2, float fac) +{ + Closure cl; + cl.absorption = mix(cl1.absorption, cl2.absorption, fac); + cl.scatter = mix(cl1.scatter, cl2.scatter, fac); + cl.emission = mix(cl1.emission, cl2.emission, fac); + cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac); + return cl; +} + +Closure closure_add(Closure cl1, Closure cl2) +{ + Closure cl; + cl.absorption = cl1.absorption + cl2.absorption; + cl.scatter = cl1.scatter + cl2.scatter; + cl.emission = cl1.emission + cl2.emission; + cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */ + return cl; +} +#else + +struct Closure { + vec3 radiance; + float opacity; + vec4 ssr_data; + vec2 ssr_normal; + int ssr_id; +}; + +#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1) + +uniform int outputSsrId; + +Closure closure_mix(Closure cl1, Closure cl2, float fac) +{ + Closure cl; + if (cl1.ssr_id == outputSsrId) { + cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); /* do not blend roughness */ + cl.ssr_normal = cl1.ssr_normal; + cl.ssr_id = cl1.ssr_id; + } + else { + cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); /* do not blend roughness */ + cl.ssr_normal = cl2.ssr_normal; + cl.ssr_id = cl2.ssr_id; + } + cl.radiance = mix(cl1.radiance, cl2.radiance, fac); + cl.opacity = mix(cl1.opacity, cl2.opacity, fac); + return cl; +} + +Closure closure_add(Closure cl1, Closure cl2) +{ + Closure cl = (cl1.ssr_id == outputSsrId) ? cl1 : cl2; + cl.radiance = cl1.radiance + cl2.radiance; + cl.opacity = cl1.opacity + cl2.opacity; + return cl; +} + +#if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) +layout(location = 0) out vec4 fragColor; +layout(location = 1) out vec4 ssrNormals; +layout(location = 2) out vec4 ssrData; + +Closure nodetree_exec(void); /* Prototype */ + +#define NODETREE_EXEC +void main() +{ + Closure cl = nodetree_exec(); + fragColor = vec4(cl.radiance, cl.opacity); + ssrNormals = cl.ssr_normal.xyyy; + ssrData = cl.ssr_data; +} + +#endif /* MESH_SHADER && !SHADOW_SHADER */ + +#endif /* VOLUMETRICS */ + +Closure nodetree_exec(void); /* Prototype */ + +/* TODO find a better place */ +#ifdef USE_MULTIPLY + +out vec4 fragColor; + +#define NODETREE_EXEC +void main() +{ + Closure cl = nodetree_exec(); + fragColor = vec4(mix(vec3(1.0), cl.radiance, cl.opacity), 1.0); +} +#endif
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl index 3997de7a22d..c7daea77782 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl @@ -6,11 +6,14 @@ uniform float invSampleCount; vec2 jitternoise = vec2(0.0); +#ifdef NOISE_SIZE void setup_noise(void) { jitternoise = texture(texJitter, gl_FragCoord.xy / NOISE_SIZE).rg; /* Global variable */ } +#endif +#ifdef HAMMERSLEY_SIZE vec3 hammersley_3d(float i, float invsamplenbr) { vec3 Xi; /* Theta, cos(Phi), sin(Phi) */ @@ -29,6 +32,7 @@ vec3 hammersley_3d(float i) { return hammersley_3d(i, invSampleCount); } +#endif /* -------------- BSDFS -------------- */ @@ -42,19 +46,30 @@ float pdf_hemisphere() return 0.5 * M_1_PI; } -vec3 sample_ggx(float nsample, float a2, vec3 N, vec3 T, vec3 B) +vec3 sample_ggx(vec3 rand, float a2) { - vec3 Xi = hammersley_3d(nsample); - /* Theta is the aperture angle of the cone */ - float z = sqrt( (1.0 - Xi.x) / ( 1.0 + a2 * Xi.x - Xi.x ) ); /* cos theta */ + float z = sqrt( (1.0 - rand.x) / ( 1.0 + a2 * rand.x - rand.x ) ); /* cos theta */ float r = sqrt( 1.0 - z * z ); /* sin theta */ - float x = r * Xi.y; - float y = r * Xi.z; + float x = r * rand.y; + float y = r * rand.z; /* Microfacet Normal */ - vec3 Ht = vec3(x, y, z); + return vec3(x, y, z); +} +vec3 sample_ggx(vec3 rand, float a2, vec3 N, vec3 T, vec3 B, out float NH) +{ + vec3 Ht = sample_ggx(rand, a2); + NH = Ht.z; + return tangent_to_world(Ht, N, T, B); +} + +#ifdef HAMMERSLEY_SIZE +vec3 sample_ggx(float nsample, float a2, vec3 N, vec3 T, vec3 B) +{ + vec3 Xi = hammersley_3d(nsample); + vec3 Ht = sample_ggx(Xi, a2); return tangent_to_world(Ht, N, T, B); } @@ -70,4 +85,5 @@ vec3 sample_hemisphere(float nsample, vec3 N, vec3 T, vec3 B) vec3 Ht = vec3(x, y, z); return tangent_to_world(Ht, N, T, B); -}
\ No newline at end of file +} +#endif
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/default_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_frag.glsl index b50eb481f94..4ba4192abbd 100644 --- a/source/blender/draw/engines/eevee/shaders/default_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/default_frag.glsl @@ -4,17 +4,15 @@ uniform float metallic; uniform float specular; uniform float roughness; -out vec4 FragColor; - -void main() +Closure nodetree_exec(void) { vec3 dielectric = vec3(0.034) * specular * 2.0; vec3 diffuse = mix(basecol, vec3(0.0), metallic); vec3 f0 = mix(dielectric, basecol, metallic); - vec3 radiance = eevee_surface_lit((gl_FrontFacing) ? worldNormal : -worldNormal, diffuse, f0, roughness, 1.0); -#if defined(USE_ALPHA_BLEND) - FragColor = vec4(radiance, 1.0); -#else - FragColor = vec4(radiance, length(viewPosition)); -#endif + vec3 ssr_spec; + vec3 radiance = eevee_surface_lit((gl_FrontFacing) ? worldNormal : -worldNormal, diffuse, f0, roughness, 1.0, 0, ssr_spec); + + Closure result = Closure(radiance, 1.0, vec4(ssr_spec, roughness), normal_encode(normalize(viewNormal), viewCameraVec), 0); + + return result; } diff --git a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl index 8e0eefec6e2..5bb9607d33c 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl @@ -46,15 +46,21 @@ out vec4 FragColor; /* -------------- Utils ------------- */ +vec3 safe_color(vec3 c) +{ + /* Clamp to avoid black square artifacts if a pixel goes NaN. */ + return clamp(c, vec3(0.0), vec3(1e20)); /* 1e20 arbitrary. */ +} + float brightness(vec3 c) { - return max(max(c.r, c.g), c.b); + return max(max(c.r, c.g), c.b); } /* 3-tap median filter */ vec3 median(vec3 a, vec3 b, vec3 c) { - return a + b + c - min(min(a, b), c) - max(max(a, b), c); + return a + b + c - min(min(a, b), c) - max(max(a, b), c); } /* ------------- Filters ------------ */ @@ -64,10 +70,10 @@ vec3 downsample_filter_high(sampler2D tex, vec2 uv, vec2 texelSize) /* Downsample with a 4x4 box filter + anti-flicker filter */ vec4 d = texelSize.xyxy * vec4(-1, -1, +1, +1); - vec3 s1 = texture(tex, uv + d.xy).rgb; - vec3 s2 = texture(tex, uv + d.zy).rgb; - vec3 s3 = texture(tex, uv + d.xw).rgb; - vec3 s4 = texture(tex, uv + d.zw).rgb; + vec3 s1 = textureLod(tex, uv + d.xy, 0.0).rgb; + vec3 s2 = textureLod(tex, uv + d.zy, 0.0).rgb; + vec3 s3 = textureLod(tex, uv + d.xw, 0.0).rgb; + vec3 s4 = textureLod(tex, uv + d.zw, 0.0).rgb; /* Karis's luma weighted average (using brightness instead of luma) */ float s1w = 1.0 / (brightness(s1) + 1.0); @@ -85,10 +91,10 @@ vec3 downsample_filter(sampler2D tex, vec2 uv, vec2 texelSize) vec4 d = texelSize.xyxy * vec4(-1, -1, +1, +1); vec3 s; - s = texture(tex, uv + d.xy).rgb; - s += texture(tex, uv + d.zy).rgb; - s += texture(tex, uv + d.xw).rgb; - s += texture(tex, uv + d.zw).rgb; + s = textureLod(tex, uv + d.xy, 0.0).rgb; + s += textureLod(tex, uv + d.zy, 0.0).rgb; + s += textureLod(tex, uv + d.xw, 0.0).rgb; + s += textureLod(tex, uv + d.zw, 0.0).rgb; return s * (1.0 / 4); } @@ -99,17 +105,17 @@ vec3 upsample_filter_high(sampler2D tex, vec2 uv, vec2 texelSize) vec4 d = texelSize.xyxy * vec4(1, 1, -1, 0) * sampleScale; vec3 s; - s = texture(tex, uv - d.xy).rgb; - s += texture(tex, uv - d.wy).rgb * 2; - s += texture(tex, uv - d.zy).rgb; + s = textureLod(tex, uv - d.xy, 0.0).rgb; + s += textureLod(tex, uv - d.wy, 0.0).rgb * 2; + s += textureLod(tex, uv - d.zy, 0.0).rgb; - s += texture(tex, uv + d.zw).rgb * 2; - s += texture(tex, uv ).rgb * 4; - s += texture(tex, uv + d.xw).rgb * 2; + s += textureLod(tex, uv + d.zw, 0.0).rgb * 2; + s += textureLod(tex, uv , 0.0).rgb * 4; + s += textureLod(tex, uv + d.xw, 0.0).rgb * 2; - s += texture(tex, uv + d.zy).rgb; - s += texture(tex, uv + d.wy).rgb * 2; - s += texture(tex, uv + d.xy).rgb; + s += textureLod(tex, uv + d.zy, 0.0).rgb; + s += textureLod(tex, uv + d.wy, 0.0).rgb * 2; + s += textureLod(tex, uv + d.xy, 0.0).rgb; return s * (1.0 / 16.0); } @@ -120,10 +126,10 @@ vec3 upsample_filter(sampler2D tex, vec2 uv, vec2 texelSize) vec4 d = texelSize.xyxy * vec4(-1, -1, +1, +1) * (sampleScale * 0.5); vec3 s; - s = texture(tex, uv + d.xy).rgb; - s += texture(tex, uv + d.zy).rgb; - s += texture(tex, uv + d.xw).rgb; - s += texture(tex, uv + d.zw).rgb; + s = textureLod(tex, uv + d.xy, 0.0).rgb; + s += textureLod(tex, uv + d.zy, 0.0).rgb; + s += textureLod(tex, uv + d.xw, 0.0).rgb; + s += textureLod(tex, uv + d.zw, 0.0).rgb; return s * (1.0 / 4.0); } @@ -136,14 +142,14 @@ vec4 step_blit(void) #ifdef HIGH_QUALITY /* Anti flicker */ vec3 d = sourceBufferTexelSize.xyx * vec3(1, 1, 0); - vec3 s0 = texture(sourceBuffer, uvcoordsvar.xy).rgb; - vec3 s1 = texture(sourceBuffer, uvcoordsvar.xy - d.xz).rgb; - vec3 s2 = texture(sourceBuffer, uvcoordsvar.xy + d.xz).rgb; - vec3 s3 = texture(sourceBuffer, uvcoordsvar.xy - d.zy).rgb; - vec3 s4 = texture(sourceBuffer, uvcoordsvar.xy + d.zy).rgb; + vec3 s0 = safe_color(textureLod(sourceBuffer, uvcoordsvar.xy, 0.0).rgb); + vec3 s1 = safe_color(textureLod(sourceBuffer, uvcoordsvar.xy - d.xz, 0.0).rgb); + vec3 s2 = safe_color(textureLod(sourceBuffer, uvcoordsvar.xy + d.xz, 0.0).rgb); + vec3 s3 = safe_color(textureLod(sourceBuffer, uvcoordsvar.xy - d.zy, 0.0).rgb); + vec3 s4 = safe_color(textureLod(sourceBuffer, uvcoordsvar.xy + d.zy, 0.0).rgb); vec3 m = median(median(s0.rgb, s1, s2), s3, s4); #else - vec3 s0 = texture(sourceBuffer, uvcoordsvar.xy).rgb; + vec3 s0 = safe_color(textureLod(sourceBuffer, uvcoordsvar.xy, 0.0).rgb); vec3 m = s0.rgb; #endif @@ -157,9 +163,6 @@ vec4 step_blit(void) /* Combine and apply the brightness response curve. */ m *= max(rq, br - curveThreshold.w) / max(br, 1e-5); - /* Clamp to avoid black square artifacts if a pixel goes NaN. */ - clamp(m, vec3(0.0), vec3(1e20)); /* 1e20 arbitrary. */ - return vec4(m, 1.0); } @@ -180,7 +183,7 @@ vec4 step_upsample(void) #else vec3 blur = upsample_filter(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize); #endif - vec3 base = texture(baseBuffer, uvcoordsvar.xy).rgb; + vec3 base = textureLod(baseBuffer, uvcoordsvar.xy, 0.0).rgb; return vec4(base + blur, 1.0); } @@ -191,7 +194,7 @@ vec4 step_resolve(void) #else vec3 blur = upsample_filter(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize); #endif - vec4 base = texture(baseBuffer, uvcoordsvar.xy); + vec4 base = textureLod(baseBuffer, uvcoordsvar.xy, 0.0); vec3 cout = base.rgb + blur * bloomIntensity; return vec4(cout, base.a); } diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl index 2f5143390ce..04648f62688 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl @@ -180,17 +180,17 @@ vec4 upsample_filter_high(sampler2D tex, vec2 uv, vec2 texelSize) vec4 d = texelSize.xyxy * vec4(1, 1, -1, 0); vec4 s; - s = texture(tex, uv - d.xy); - s += texture(tex, uv - d.wy) * 2; - s += texture(tex, uv - d.zy); + s = textureLod(tex, uv - d.xy, 0.0); + s += textureLod(tex, uv - d.wy, 0.0) * 2; + s += textureLod(tex, uv - d.zy, 0.0); - s += texture(tex, uv + d.zw) * 2; - s += texture(tex, uv ) * 4; - s += texture(tex, uv + d.xw) * 2; + s += textureLod(tex, uv + d.zw, 0.0) * 2; + s += textureLod(tex, uv , 0.0) * 4; + s += textureLod(tex, uv + d.xw, 0.0) * 2; - s += texture(tex, uv + d.zy); - s += texture(tex, uv + d.wy) * 2; - s += texture(tex, uv + d.xy); + s += textureLod(tex, uv + d.zy, 0.0); + s += textureLod(tex, uv + d.wy, 0.0) * 2; + s += textureLod(tex, uv + d.xy, 0.0); return s * (1.0 / 16.0); } @@ -201,10 +201,10 @@ vec4 upsample_filter(sampler2D tex, vec2 uv, vec2 texelSize) vec4 d = texelSize.xyxy * vec4(-1, -1, +1, +1) * 0.5; vec4 s; - s = texture(tex, uv + d.xy); - s += texture(tex, uv + d.zy); - s += texture(tex, uv + d.xw); - s += texture(tex, uv + d.zw); + s = textureLod(tex, uv + d.xy, 0.0); + s += textureLod(tex, uv + d.zy, 0.0); + s += textureLod(tex, uv + d.xw, 0.0); + s += textureLod(tex, uv + d.zw, 0.0); return s * (1.0 / 4.0); } @@ -213,7 +213,7 @@ vec4 upsample_filter(sampler2D tex, vec2 uv, vec2 texelSize) void step_resolve(void) { /* Recompute Near / Far CoC */ - float depth = texture(depthBuffer, uvcoord).r; + float depth = textureLod(depthBuffer, uvcoord, 0.0).r; float zdepth = linear_depth(depth); float coc_signed = calculate_coc(zdepth); float coc_far = max(-coc_signed, 0.0); @@ -221,7 +221,7 @@ void step_resolve(void) /* Recompute Near / Far CoC */ vec2 texelSize = 1.0 / vec2(textureSize(farBuffer, 0)); - vec4 srccolor = texture(colorBuffer, uvcoord); + vec4 srccolor = textureLod(colorBuffer, uvcoord, 0.0); vec4 farcolor = upsample_filter_high(farBuffer, uvcoord, texelSize); vec4 nearcolor = upsample_filter_high(nearBuffer, uvcoord, texelSize); diff --git a/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl new file mode 100644 index 00000000000..1e57aec5ea2 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl @@ -0,0 +1,15 @@ +/** + * Simple downsample shader. Takes the average of the 4 texels of lower mip. + **/ + +uniform sampler2D source; + +out vec4 FragColor; + +void main() +{ + /* Reconstructing Target uvs like this avoid missing pixels if NPO2 */ + vec2 uvs = gl_FragCoord.xy * 2.0 / vec2(textureSize(source, 0)); + + FragColor = textureLod(source, uvs, 0.0); +}
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl index 9f81206070b..3d580d0ce39 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl @@ -4,63 +4,61 @@ * Adapted from http://rastergrid.com/blog/2010/10/hierarchical-z-map-based-occlusion-culling/ **/ +#ifdef LAYERED +uniform sampler2DArray depthBuffer; +uniform int depthLayer; +#else uniform sampler2D depthBuffer; +#endif -out vec4 FragMinMax; - -vec2 sampleLowerMip(ivec2 texel) +float sampleLowerMip(ivec2 texel) { -#ifdef INPUT_DEPTH - return texelFetch(depthBuffer, texel, 0).rr; +#ifdef LAYERED + return texelFetch(depthBuffer, ivec3(texel, depthLayer), 0).r; #else - return texelFetch(depthBuffer, texel, 0).rg; + return texelFetch(depthBuffer, texel, 0).r; #endif } -void minmax(inout vec2 val[2]) +void minmax(inout float out_val, float in_val) { - val[0].x = min(val[0].x, val[1].x); - val[0].y = max(val[0].y, val[1].y); +#ifdef MIN_PASS + out_val = min(out_val, in_val); +#else /* MAX_PASS */ + out_val = max(out_val, in_val); +#endif } void main() { - vec2 val[2]; ivec2 texelPos = ivec2(gl_FragCoord.xy); - ivec2 mipsize = textureSize(depthBuffer, 0); + ivec2 mipsize = textureSize(depthBuffer, 0).xy; + #ifndef COPY_DEPTH texelPos *= 2; #endif - val[0] = sampleLowerMip(texelPos); + float val = sampleLowerMip(texelPos); #ifndef COPY_DEPTH - val[1] = sampleLowerMip(texelPos + ivec2(1, 0)); - minmax(val); - val[1] = sampleLowerMip(texelPos + ivec2(1, 1)); - minmax(val); - val[1] = sampleLowerMip(texelPos + ivec2(0, 1)); - minmax(val); + minmax(val, sampleLowerMip(texelPos + ivec2(1, 0))); + minmax(val, sampleLowerMip(texelPos + ivec2(1, 1))); + minmax(val, sampleLowerMip(texelPos + ivec2(0, 1))); /* if we are reducing an odd-width texture then fetch the edge texels */ if (((mipsize.x & 1) != 0) && (int(gl_FragCoord.x) == mipsize.x-3)) { /* if both edges are odd, fetch the top-left corner texel */ if (((mipsize.y & 1) != 0) && (int(gl_FragCoord.y) == mipsize.y-3)) { - val[1] = sampleLowerMip(texelPos + ivec2(-1, -1)); - minmax(val); + minmax(val, sampleLowerMip(texelPos + ivec2(-1, -1))); } - val[1] = sampleLowerMip(texelPos + ivec2(0, -1)); - minmax(val); - val[1] = sampleLowerMip(texelPos + ivec2(1, -1)); - minmax(val); + minmax(val, sampleLowerMip(texelPos + ivec2(0, -1))); + minmax(val, sampleLowerMip(texelPos + ivec2(1, -1))); } /* if we are reducing an odd-height texture then fetch the edge texels */ else if (((mipsize.y & 1) != 0) && (int(gl_FragCoord.y) == mipsize.y-3)) { - val[1] = sampleLowerMip(texelPos + ivec2(0, -1)); - minmax(val); - val[1] = sampleLowerMip(texelPos + ivec2(1, -1)); - minmax(val); + minmax(val, sampleLowerMip(texelPos + ivec2(0, -1))); + minmax(val, sampleLowerMip(texelPos + ivec2(1, -1))); } #endif - FragMinMax = vec4(val[0], 0.0, 1.0); + gl_FragDepth = val; }
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl index 045fcd11fae..1a01db3a1a3 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl @@ -59,7 +59,7 @@ void main() FragColor = vec4(0.0, 0.0, 0.0, 1.0); for (int j = 0; j < samples && j < MAX_SAMPLE; j++) { - FragColor += texture(colorBuffer, uvcoordsvar.xy + motion * i) * inv_samples; + FragColor += textureLod(colorBuffer, uvcoordsvar.xy + motion * i, 0.0) * inv_samples; i += inc; } } diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl new file mode 100644 index 00000000000..8e5ffb37e2e --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl @@ -0,0 +1,449 @@ + +/* Based on Stochastic Screen Space Reflections + * https://www.ea.com/frostbite/news/stochastic-screen-space-reflections */ + +#ifndef UTIL_TEX +#define UTIL_TEX +uniform sampler2DArray utilTex; +#endif /* UTIL_TEX */ + +uniform int rayCount; +uniform float maxRoughness; + +#define BRDF_BIAS 0.7 + +vec3 generate_ray(vec3 V, vec3 N, float a2, vec3 rand, out float pdf) +{ + float NH; + vec3 T, B; + make_orthonormal_basis(N, T, B); /* Generate tangent space */ + + /* Importance sampling bias */ + rand.x = mix(rand.x, 0.0, BRDF_BIAS); + + /* TODO distribution of visible normals */ + vec3 H = sample_ggx(rand, a2, N, T, B, NH); /* Microfacet normal */ + pdf = min(1024e32, pdf_ggx_reflect(NH, a2)); /* Theoretical limit of 16bit float */ + return reflect(-V, H); +} + +#define MAX_MIP 9.0 + +#ifdef STEP_RAYTRACE + +uniform sampler2D normalBuffer; +uniform sampler2D specroughBuffer; + +uniform int planar_count; + +layout(location = 0) out vec4 hitData0; +layout(location = 1) out vec4 hitData1; +layout(location = 2) out vec4 hitData2; +layout(location = 3) out vec4 hitData3; + +bool has_hit_backface(vec3 hit_pos, vec3 R, vec3 V) +{ + vec2 hit_co = project_point(ProjectionMatrix, hit_pos).xy * 0.5 + 0.5; + vec3 hit_N = normal_decode(textureLod(normalBuffer, hit_co, 0.0).rg, V); + return (dot(-R, hit_N) < 0.0); +} + +vec4 do_planar_ssr(int index, vec3 V, vec3 N, vec3 planeNormal, vec3 viewPosition, float a2, vec3 rand, float ray_nbr) +{ + float pdf; + vec3 R = generate_ray(V, N, a2, rand, pdf); + + R = reflect(R, planeNormal); + pdf *= -1.0; /* Tag as planar ray. */ + + /* If ray is bad (i.e. going below the plane) do not trace. */ + if (dot(R, planeNormal) > 0.0) { + vec3 R = generate_ray(V, N, a2, rand * vec3(1.0, -1.0, -1.0), pdf); + } + + vec3 hit_pos; + if (abs(dot(-R, V)) < 0.9999) { + /* Since viewspace hit position can land behind the camera in this case, + * we save the reflected view position (visualize it as the hit position + * below the reflection plane). This way it's garanted that the hit will + * be in front of the camera. That let us tag the bad rays with a negative + * sign in the Z component. */ + hit_pos = raycast(index, viewPosition, R, fract(rand.x + (ray_nbr / float(rayCount))), a2); + } + else { + vec2 uvs = project_point(ProjectionMatrix, viewPosition).xy * 0.5 + 0.5; + float raw_depth = textureLod(planarDepth, vec3(uvs, float(index)), 0.0).r; + hit_pos = get_view_space_from_depth(uvs, raw_depth); + hit_pos.z *= (raw_depth < 1.0) ? 1.0 : -1.0; + } + + return vec4(hit_pos, pdf); +} + +vec4 do_ssr(vec3 V, vec3 N, vec3 viewPosition, float a2, vec3 rand, float ray_nbr) +{ + float pdf; + vec3 R = generate_ray(V, N, a2, rand, pdf); + + vec3 hit_pos = raycast(-1, viewPosition, R, fract(rand.x + (ray_nbr / float(rayCount))), a2); + + return vec4(hit_pos, pdf); +} + +void main() +{ +#ifdef FULLRES + ivec2 fullres_texel = ivec2(gl_FragCoord.xy); + ivec2 halfres_texel = fullres_texel; +#else + ivec2 fullres_texel = ivec2(gl_FragCoord.xy) * 2; + ivec2 halfres_texel = ivec2(gl_FragCoord.xy); +#endif + + float depth = texelFetch(depthBuffer, fullres_texel, 0).r; + + /* Early out */ + if (depth == 1.0) + discard; + + vec2 uvs = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0)); +#ifndef FULLRES + uvs *= 2.0; +#endif + + /* Using view space */ + vec3 viewPosition = get_view_space_from_depth(uvs, depth); + vec3 V = viewCameraVec; + vec3 N = normal_decode(texelFetch(normalBuffer, fullres_texel, 0).rg, V); + + /* Retrieve pixel data */ + vec4 speccol_roughness = texelFetch(specroughBuffer, fullres_texel, 0).rgba; + + /* Early out */ + if (dot(speccol_roughness.rgb, vec3(1.0)) == 0.0) + discard; + + + float roughness = speccol_roughness.a; + float roughnessSquared = max(1e-3, roughness * roughness); + float a2 = roughnessSquared * roughnessSquared; + + if (roughness > maxRoughness + 0.2) { + hitData0 = hitData1 = hitData2 = hitData3 = vec4(0.0); + return; + } + + vec3 rand = texelFetch(utilTex, ivec3(halfres_texel % LUT_SIZE, 2), 0).rba; + + vec3 worldPosition = transform_point(ViewMatrixInverse, viewPosition); + vec3 wN = transform_direction(ViewMatrixInverse, N); + + /* Planar Reflections */ + for (int i = 0; i < MAX_PLANAR && i < planar_count; ++i) { + PlanarData pd = planars_data[i]; + + float fade = probe_attenuation_planar(pd, worldPosition, wN, 0.0); + + if (fade > 0.5) { + /* Find view vector / reflection plane intersection. */ + /* TODO optimize, use view space for all. */ + vec3 tracePosition = line_plane_intersect(worldPosition, cameraVec, pd.pl_plane_eq); + tracePosition = transform_point(ViewMatrix, tracePosition); + vec3 planeNormal = transform_direction(ViewMatrix, pd.pl_normal); + + /* TODO : Raytrace together if textureGather is supported. */ + hitData0 = do_planar_ssr(i, V, N, planeNormal, tracePosition, a2, rand, 0.0); + if (rayCount > 1) hitData1 = do_planar_ssr(i, V, N, planeNormal, tracePosition, a2, rand.xyz * vec3(1.0, -1.0, -1.0), 1.0); + if (rayCount > 2) hitData2 = do_planar_ssr(i, V, N, planeNormal, tracePosition, a2, rand.xzy * vec3(1.0, 1.0, -1.0), 2.0); + if (rayCount > 3) hitData3 = do_planar_ssr(i, V, N, planeNormal, tracePosition, a2, rand.xzy * vec3(1.0, -1.0, 1.0), 3.0); + return; + } + } + + /* TODO : Raytrace together if textureGather is supported. */ + hitData0 = do_ssr(V, N, viewPosition, a2, rand, 0.0); + if (rayCount > 1) hitData1 = do_ssr(V, N, viewPosition, a2, rand.xyz * vec3(1.0, -1.0, -1.0), 1.0); + if (rayCount > 2) hitData2 = do_ssr(V, N, viewPosition, a2, rand.xzy * vec3(1.0, 1.0, -1.0), 2.0); + if (rayCount > 3) hitData3 = do_ssr(V, N, viewPosition, a2, rand.xzy * vec3(1.0, -1.0, 1.0), 3.0); +} + +#else /* STEP_RESOLVE */ + +uniform sampler2D colorBuffer; /* previous frame */ +uniform sampler2D normalBuffer; +uniform sampler2D specroughBuffer; + +uniform sampler2D hitBuffer0; +uniform sampler2D hitBuffer1; +uniform sampler2D hitBuffer2; +uniform sampler2D hitBuffer3; + +uniform int probe_count; +uniform int planar_count; + +uniform float borderFadeFactor; +uniform float fireflyFactor; + +uniform mat4 PastViewProjectionMatrix; + +out vec4 fragColor; + +void fallback_cubemap(vec3 N, vec3 V, vec3 W, float roughness, float roughnessSquared, inout vec4 spec_accum) +{ + /* Specular probes */ + vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared); + + /* Starts at 1 because 0 is world probe */ + for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) { + CubeData cd = probes_data[i]; + + float fade = probe_attenuation_cube(cd, W); + + if (fade > 0.0) { + vec3 spec = probe_evaluate_cube(float(i), cd, W, spec_dir, roughness); + accumulate_light(spec, fade, spec_accum); + } + } + + /* World Specular */ + if (spec_accum.a < 0.999) { + vec3 spec = probe_evaluate_world_spec(spec_dir, roughness); + accumulate_light(spec, 1.0, spec_accum); + } +} + +#if 0 /* Finish reprojection with motion vectors */ +vec3 get_motion_vector(vec3 pos) +{ +} + +/* http://bitsquid.blogspot.fr/2017/06/reprojecting-reflections_22.html */ +vec3 find_reflection_incident_point(vec3 cam, vec3 hit, vec3 pos, vec3 N) +{ + float d_cam = point_plane_projection_dist(cam, pos, N); + float d_hit = point_plane_projection_dist(hit, pos, N); + + if (d_hit < d_cam) { + /* Swap */ + float tmp = d_cam; + d_cam = d_hit; + d_hit = tmp; + } + + vec3 proj_cam = cam - (N * d_cam); + vec3 proj_hit = hit - (N * d_hit); + + return (proj_hit - proj_cam) * d_cam / (d_cam + d_hit) + proj_cam; +} +#endif + +float brightness(vec3 c) +{ + return max(max(c.r, c.g), c.b); +} + +float screen_border_mask(vec2 hit_co) +{ + const float margin = 0.003; + float atten = borderFadeFactor + margin; /* Screen percentage */ + hit_co = smoothstep(margin, atten, hit_co) * (1 - smoothstep(1.0 - atten, 1.0 - margin, hit_co)); + + float screenfade = hit_co.x * hit_co.y; + + return screenfade; +} + +vec2 get_reprojected_reflection(vec3 hit, vec3 pos, vec3 N) +{ + /* TODO real reprojection with motion vectors, etc... */ + return project_point(PastViewProjectionMatrix, hit).xy * 0.5 + 0.5; +} + +vec4 get_ssr_sample( + sampler2D hitBuffer, PlanarData pd, float planar_index, vec3 worldPosition, vec3 N, vec3 V, float roughnessSquared, + float cone_tan, vec2 source_uvs, vec2 texture_size, ivec2 target_texel, + inout float weight_acc) +{ + vec4 hit_co_pdf = texelFetch(hitBuffer, target_texel, 0).rgba; + bool has_hit = (hit_co_pdf.z < 0.0); + bool is_planar = (hit_co_pdf.w < 0.0); + hit_co_pdf.z = -abs(hit_co_pdf.z); + hit_co_pdf.w = abs(hit_co_pdf.w); + + /* Hit position in world space. */ + vec3 hit_pos = transform_point(ViewMatrixInverse, hit_co_pdf.xyz); + + vec2 ref_uvs; + vec3 L; + float mask = 1.0; + float cone_footprint; + if (is_planar) { + /* Reflect back the hit position to have it in non-reflected world space */ + vec3 trace_pos = line_plane_intersect(worldPosition, V, pd.pl_plane_eq); + vec3 hit_vec = hit_pos - trace_pos; + hit_vec = reflect(hit_vec, pd.pl_normal); + hit_pos = hit_vec + trace_pos; + L = normalize(hit_vec); + ref_uvs = project_point(ProjectionMatrix, hit_co_pdf.xyz).xy * 0.5 + 0.5; + vec2 uvs = gl_FragCoord.xy / texture_size; + + /* Compute cone footprint in screen space. */ + float homcoord = ProjectionMatrix[2][3] * hit_co_pdf.z + ProjectionMatrix[3][3]; + cone_footprint = length(hit_vec) * cone_tan * ProjectionMatrix[0][0] / homcoord; + } + else { + /* Find hit position in previous frame. */ + ref_uvs = get_reprojected_reflection(hit_pos, worldPosition, N); + L = normalize(hit_pos - worldPosition); + vec2 uvs = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0)); + mask *= screen_border_mask(uvs); + + /* Compute cone footprint Using UV distance because we are using screen space filtering. */ + cone_footprint = cone_tan * distance(ref_uvs, source_uvs); + } + mask = min(mask, screen_border_mask(ref_uvs)); + mask *= float(has_hit); + + /* Estimate a cone footprint to sample a corresponding mipmap level. */ + float mip = BRDF_BIAS * clamp(log2(cone_footprint * max(texture_size.x, texture_size.y)), 0.0, MAX_MIP) - 1.0; + + /* Slide 54 */ + float bsdf = bsdf_ggx(N, L, V, roughnessSquared); + float weight = step(1e-8, hit_co_pdf.w) * bsdf / max(1e-8, hit_co_pdf.w); + weight_acc += weight; + + vec3 sample; + if (is_planar) { + sample = textureLod(probePlanars, vec3(ref_uvs, planar_index), mip).rgb; + } + else { + sample = textureLod(colorBuffer, ref_uvs, mip).rgb; + } + + /* Clamped brightness. */ + float luma = max(1e-8, brightness(sample)); + sample *= 1.0 - max(0.0, luma - fireflyFactor) / luma; + + /* Do not add light if ray has failed. */ + sample *= float(has_hit); + + return vec4(sample, mask) * weight; +} + +#define NUM_NEIGHBORS 4 + +void main() +{ + ivec2 fullres_texel = ivec2(gl_FragCoord.xy); +#ifdef FULLRES + ivec2 halfres_texel = fullres_texel; +#else + ivec2 halfres_texel = ivec2(gl_FragCoord.xy / 2.0); +#endif + vec2 texture_size = vec2(textureSize(depthBuffer, 0)); + vec2 uvs = gl_FragCoord.xy / texture_size; + vec3 rand = texelFetch(utilTex, ivec3(fullres_texel % LUT_SIZE, 2), 0).rba; + + float depth = textureLod(depthBuffer, uvs, 0.0).r; + + /* Early out */ + if (depth == 1.0) + discard; + + /* Using world space */ + vec3 viewPosition = get_view_space_from_depth(uvs, depth); /* Needed for viewCameraVec */ + vec3 worldPosition = transform_point(ViewMatrixInverse, viewPosition); + vec3 V = cameraVec; + vec3 vN = normal_decode(texelFetch(normalBuffer, fullres_texel, 0).rg, viewCameraVec); + vec3 N = transform_direction(ViewMatrixInverse, vN); + vec4 speccol_roughness = texelFetch(specroughBuffer, fullres_texel, 0).rgba; + + /* Early out */ + if (dot(speccol_roughness.rgb, vec3(1.0)) == 0.0) + discard; + + /* Find Planar Reflections affecting this pixel */ + PlanarData pd; + float planar_index; + for (int i = 0; i < MAX_PLANAR && i < planar_count; ++i) { + pd = planars_data[i]; + + float fade = probe_attenuation_planar(pd, worldPosition, N, 0.0); + + if (fade > 0.5) { + planar_index = float(i); + break; + } + } + + float roughness = speccol_roughness.a; + float roughnessSquared = max(1e-3, roughness * roughness); + + vec4 spec_accum = vec4(0.0); + + /* Resolve SSR */ + float cone_cos = cone_cosine(roughnessSquared); + float cone_tan = sqrt(1 - cone_cos * cone_cos) / cone_cos; + cone_tan *= mix(saturate(dot(N, V) * 2.0), 1.0, roughness); /* Elongation fit */ + + vec2 source_uvs = project_point(PastViewProjectionMatrix, worldPosition).xy * 0.5 + 0.5; + + vec4 ssr_accum = vec4(0.0); + float weight_acc = 0.0; + const ivec2 neighbors[9] = ivec2[9]( + ivec2(0, 0), + + ivec2(0, 1), + ivec2(-1, -1), ivec2(1, -1), + + ivec2(-1, 1), ivec2(1, 1), + ivec2(0, -1), + + ivec2(-1, 0), ivec2(1, 0) + ); + ivec2 invert_neighbor; + invert_neighbor.x = ((fullres_texel.x & 0x1) == 0) ? 1 : -1; + invert_neighbor.y = ((fullres_texel.y & 0x1) == 0) ? 1 : -1; + + if (roughness < maxRoughness + 0.2) { + for (int i = 0; i < NUM_NEIGHBORS; i++) { + ivec2 target_texel = halfres_texel + neighbors[i] * invert_neighbor; + + ssr_accum += get_ssr_sample(hitBuffer0, pd, planar_index, worldPosition, N, V, + roughnessSquared, cone_tan, source_uvs, + texture_size, target_texel, weight_acc); + if (rayCount > 1) { + ssr_accum += get_ssr_sample(hitBuffer1, pd, planar_index, worldPosition, N, V, + roughnessSquared, cone_tan, source_uvs, + texture_size, target_texel, weight_acc); + } + if (rayCount > 2) { + ssr_accum += get_ssr_sample(hitBuffer2, pd, planar_index, worldPosition, N, V, + roughnessSquared, cone_tan, source_uvs, + texture_size, target_texel, weight_acc); + } + if (rayCount > 3) { + ssr_accum += get_ssr_sample(hitBuffer3, pd, planar_index, worldPosition, N, V, + roughnessSquared, cone_tan, source_uvs, + texture_size, target_texel, weight_acc); + } + } + } + + /* Compute SSR contribution */ + if (weight_acc > 0.0) { + ssr_accum /= weight_acc; + /* fade between 0.5 and 1.0 roughness */ + ssr_accum.a *= smoothstep(maxRoughness + 0.2, maxRoughness, roughness); + accumulate_light(ssr_accum.rgb, ssr_accum.a, spec_accum); + } + + /* If SSR contribution is not 1.0, blend with cubemaps */ + if (spec_accum.a < 1.0) { + fallback_cubemap(N, V, worldPosition, roughness, roughnessSquared, spec_accum); + } + + fragColor = vec4(spec_accum.rgb * speccol_roughness.rgb, 1.0); +} + +#endif diff --git a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl index 061719b5685..75ec5ade58d 100644 --- a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl @@ -8,18 +8,6 @@ layout(std140) uniform shadow_block { ShadowCascadeData shadows_cascade_data[MAX_SHADOW_CASCADE]; }; -layout(std140) uniform probe_block { - CubeData probes_data[MAX_PROBE]; -}; - -layout(std140) uniform grid_block { - GridData grids_data[MAX_GRID]; -}; - -layout(std140) uniform planar_block { - PlanarData planars_data[MAX_PLANAR]; -}; - layout(std140) uniform light_block { LightData lights_data[MAX_LIGHT]; }; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl index 32da31339d1..0200b32d969 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl @@ -60,6 +60,28 @@ struct GridData { #define g_resolution resolution_offset.xyz #define g_offset resolution_offset.w +#ifndef MAX_PROBE +#define MAX_PROBE 1 +#endif +#ifndef MAX_GRID +#define MAX_GRID 1 +#endif +#ifndef MAX_PLANAR +#define MAX_PLANAR 1 +#endif + +layout(std140) uniform probe_block { + CubeData probes_data[MAX_PROBE]; +}; + +layout(std140) uniform grid_block { + GridData grids_data[MAX_GRID]; +}; + +layout(std140) uniform planar_block { + PlanarData planars_data[MAX_PLANAR]; +}; + /* ----------- Functions --------- */ float probe_attenuation_cube(CubeData pd, vec3 W) @@ -78,7 +100,7 @@ float probe_attenuation_cube(CubeData pd, vec3 W) return fac; } -float probe_attenuation_planar(PlanarData pd, vec3 W, vec3 N) +float probe_attenuation_planar(PlanarData pd, vec3 W, vec3 N, float roughness) { /* Normal Facing */ float fac = saturate(dot(pd.pl_normal, N) * pd.pl_facing_scale + pd.pl_facing_bias); @@ -92,6 +114,9 @@ float probe_attenuation_planar(PlanarData pd, vec3 W, vec3 N) dist_to_clip.y = dot(pd.pl_clip_pos_y, W); fac *= step(2.0, dot(step(pd.pl_clip_edges, dist_to_clip.xxyy), vec2(-1.0, 1.0).xyxy)); /* compare and add all tests */ + /* Decrease influence for high roughness */ + fac *= saturate(1.0 - roughness * 10.0); + return fac; } @@ -107,7 +132,7 @@ vec3 probe_evaluate_cube(float id, CubeData cd, vec3 W, vec3 R, float roughness) { /* Correct reflection ray using parallax volume intersection. */ vec3 localpos = transform_point(cd.parallaxmat, W); - vec3 localray = mat3(cd.parallaxmat) * R; + vec3 localray = transform_direction(cd.parallaxmat, R); float dist; if (cd.p_parallax_type == PROBE_PARALLAX_BOX) { @@ -142,20 +167,14 @@ vec3 probe_evaluate_world_spec(vec3 R, float roughness) vec3 probe_evaluate_planar( float id, PlanarData pd, vec3 W, vec3 N, vec3 V, - float rand, vec3 camera_pos, float roughness, + float rand, float roughness, inout float fade) { - /* Sample reflection depth. */ - vec4 refco = pd.reflectionmat * vec4(W, 1.0); - refco.xy /= refco.w; - float ref_depth = textureLod(probePlanars, vec3(refco.xy, id), 0.0).a; - - /* Find view vector / reflection plane intersection. (dist_to_plane is negative) */ - float dist_to_plane = line_plane_intersect_dist(camera_pos, V, pd.pl_plane_eq); - vec3 point_on_plane = camera_pos + V * dist_to_plane; + /* Find view vector / reflection plane intersection. */ + vec3 point_on_plane = line_plane_intersect(W, V, pd.pl_plane_eq); /* How far the pixel is from the plane. */ - ref_depth = ref_depth + dist_to_plane; + float ref_depth = 1.0; /* TODO parameter */ /* Compute distorded reflection vector based on the distance to the reflected object. * In other words find intersection between reflection vector and the sphere center @@ -166,24 +185,12 @@ vec3 probe_evaluate_planar( vec3 ref_pos = point_on_plane + proj_ref; /* Reproject to find texture coords. */ - refco = pd.reflectionmat * vec4(ref_pos, 1.0); + vec4 refco = ViewProjectionMatrix * vec4(ref_pos, 1.0); refco.xy /= refco.w; - /* Distance to roughness */ - float linear_roughness = sqrt(roughness); - float distance_roughness = min(linear_roughness, ref_depth * linear_roughness); - linear_roughness = mix(distance_roughness, linear_roughness, linear_roughness); - - /* Decrease influence for high roughness */ - fade *= saturate((1.0 - linear_roughness) * 5.0 - 2.0); - - float lod = linear_roughness * 2.5 * lodPlanarMax; - vec3 sample = textureLod(probePlanars, vec3(refco.xy, id), lod).rgb; - - /* Use a second sample randomly rotated to blur out the lowres aspect */ - vec2 rot_sample = (1.0 / vec2(textureSize(probePlanars, 0).xy)) * vec2(cos(rand * M_2PI), sin(rand * M_2PI)) * lod; - sample += textureLod(probePlanars, vec3(refco.xy + rot_sample, id), lod).rgb; - sample *= 0.5; + /* TODO: If we support non-ssr planar reflection, we should blur them with gaussian + * and chose the right mip depending on the cone footprint after projection */ + vec3 sample = textureLod(probePlanars, vec3(refco.xy * 0.5 + 0.5, id), 0.0).rgb; return sample; } diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl index 2cb43336ace..676f7e49ebf 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl @@ -1,10 +1,6 @@ uniform int probeIdx; -layout(std140) uniform planar_block { - PlanarData planars_data[MAX_PLANAR]; -}; - in vec3 worldPosition; out vec4 FragColor; @@ -23,7 +19,7 @@ void main() discard; } - vec4 refco = pd.reflectionmat * vec4(worldPosition, 1.0); + vec4 refco = ViewProjectionMatrix * vec4(worldPosition, 1.0); refco.xy /= refco.w; - FragColor = vec4(textureLod(probePlanars, vec3(refco.xy, float(probeIdx)), 0.0).rgb, 1.0); + FragColor = vec4(textureLod(probePlanars, vec3(refco.xy * 0.5 + 0.5, float(probeIdx)), 0.0).rgb, 1.0); } diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl index fa70fb5590f..c2ef085ca01 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl @@ -13,8 +13,9 @@ out vec4 FragColor; void main() { /* Reconstructing Target uvs like this avoid missing pixels */ - vec2 uvs = floor(gl_FragCoord.xy) * 2.0 * texelSize + texelSize; + vec2 uvs = gl_FragCoord.xy * 2.0 / vec2(textureSize(source, 0).xy); +#if 0 /* Slower and does not match the main framebuffer downsampling. */ /* Downsample with a 4x4 box filter */ vec4 d = texelSize.xyxy * vec4(-1, -1, +1, +1); @@ -24,4 +25,7 @@ void main() FragColor += texture(source, vec3(uvs + d.zw, layer)).rgba; FragColor /= 4.0; +#endif + + FragColor = texture(source, vec3(uvs, layer)); }
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl index 1cfc00ef8d7..21202a10fb0 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -5,6 +5,7 @@ uniform int grid_count; uniform int planar_count; uniform bool specToggle; +uniform bool ssrToggle; #ifndef UTIL_TEX #define UTIL_TEX @@ -24,7 +25,7 @@ in vec3 viewNormal; /* ----------- default ----------- */ -vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao) +vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao, int ssr_id, out vec3 ssr_spec) { /* Zero length vectors cause issues, see: T51979. */ #if 0 @@ -89,37 +90,40 @@ vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao) /* Accumulate light from all sources until accumulator is full. Then apply Occlusion and BRDF. */ vec4 spec_accum = vec4(0.0); - /* Planar Reflections */ - for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999; ++i) { - PlanarData pd = planars_data[i]; + /* SSR lobe is applied later in a defered style */ + if (!(ssrToggle && ssr_id == outputSsrId)) { + /* Planar Reflections */ + for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999; ++i) { + PlanarData pd = planars_data[i]; - float fade = probe_attenuation_planar(pd, worldPosition, N); + float fade = probe_attenuation_planar(pd, worldPosition, N, roughness); - if (fade > 0.0) { - vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, cameraPos, roughness, fade); - accumulate_light(spec, fade, spec_accum); + if (fade > 0.0) { + vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, roughness, fade); + accumulate_light(spec, fade, spec_accum); + } } - } - /* Specular probes */ - vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared); + /* Specular probes */ + vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared); - /* Starts at 1 because 0 is world probe */ - for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) { - CubeData cd = probes_data[i]; + /* Starts at 1 because 0 is world probe */ + for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) { + CubeData cd = probes_data[i]; - float fade = probe_attenuation_cube(cd, worldPosition); + float fade = probe_attenuation_cube(cd, worldPosition); - if (fade > 0.0) { - vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness); - accumulate_light(spec, fade, spec_accum); + if (fade > 0.0) { + vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness); + accumulate_light(spec, fade, spec_accum); + } } - } - /* World Specular */ - if (spec_accum.a < 0.999) { - vec3 spec = probe_evaluate_world_spec(spec_dir, roughness); - accumulate_light(spec, 1.0, spec_accum); + /* World Specular */ + if (spec_accum.a < 0.999) { + vec3 spec = probe_evaluate_world_spec(spec_dir, roughness); + accumulate_light(spec, 1.0, spec_accum); + } } /* Ambient Occlusion */ @@ -130,7 +134,8 @@ vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao) vec2 uv = lut_coords(dot(N, V), roughness); vec2 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rg; - out_light += spec_accum.rgb * F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness) * float(specToggle); + ssr_spec = F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness); + out_light += spec_accum.rgb * ssr_spec * float(specToggle); /* ---------------- DIFFUSE ENVIRONMENT LIGHTING ----------------- */ @@ -166,7 +171,7 @@ vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao) vec3 eevee_surface_clearcoat_lit( vec3 N, vec3 albedo, vec3 f0, float roughness, vec3 C_N, float C_intensity, float C_roughness, /* Clearcoat params */ - float ao) + float ao, int ssr_id, out vec3 ssr_spec) { roughness = clamp(roughness, 1e-8, 0.9999); float roughnessSquared = roughness * roughness; @@ -230,13 +235,15 @@ vec3 eevee_surface_clearcoat_lit( PlanarData pd = planars_data[i]; /* Fade on geometric normal. */ - float fade = probe_attenuation_planar(pd, worldPosition, worldNormal); + float fade = probe_attenuation_planar(pd, worldPosition, worldNormal, roughness); if (fade > 0.0) { - vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, cameraPos, roughness, fade); - accumulate_light(spec, fade, spec_accum); + if (!(ssrToggle && ssr_id == outputSsrId)) { + vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, roughness, fade); + accumulate_light(spec, fade, spec_accum); + } - vec3 C_spec = probe_evaluate_planar(float(i), pd, worldPosition, C_N, V, rand.r, cameraPos, C_roughness, fade); + vec3 C_spec = probe_evaluate_planar(float(i), pd, worldPosition, C_N, V, rand.r, C_roughness, fade); accumulate_light(C_spec, fade, C_spec_accum); } } @@ -252,8 +259,10 @@ vec3 eevee_surface_clearcoat_lit( float fade = probe_attenuation_cube(cd, worldPosition); if (fade > 0.0) { - vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness); - accumulate_light(spec, fade, spec_accum); + if (!(ssrToggle && ssr_id == outputSsrId)) { + vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness); + accumulate_light(spec, fade, spec_accum); + } vec3 C_spec = probe_evaluate_cube(float(i), cd, worldPosition, C_spec_dir, C_roughness); accumulate_light(C_spec, fade, C_spec_accum); @@ -262,8 +271,10 @@ vec3 eevee_surface_clearcoat_lit( /* World Specular */ if (spec_accum.a < 0.999) { - vec3 spec = probe_evaluate_world_spec(spec_dir, roughness); - accumulate_light(spec, 1.0, spec_accum); + if (!(ssrToggle && ssr_id == outputSsrId)) { + vec3 spec = probe_evaluate_world_spec(spec_dir, roughness); + accumulate_light(spec, 1.0, spec_accum); + } vec3 C_spec = probe_evaluate_world_spec(C_spec_dir, C_roughness); accumulate_light(C_spec, 1.0, C_spec_accum); @@ -277,7 +288,8 @@ vec3 eevee_surface_clearcoat_lit( vec2 uv = lut_coords(dot(N, V), roughness); vec2 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rg; - out_light += spec_accum.rgb * F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness) * float(specToggle); + ssr_spec = F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness); + out_light += spec_accum.rgb * ssr_spec * float(specToggle); uv = lut_coords(dot(C_N, V), C_roughness); brdf_lut = texture(utilTex, vec3(uv, 1.0)).rg; @@ -392,7 +404,7 @@ vec3 eevee_surface_diffuse_lit(vec3 N, vec3 albedo, float ao) /* ----------- Glossy ----------- */ -vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao) +vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao, int ssr_id, out vec3 ssr_spec) { roughness = clamp(roughness, 1e-8, 0.9999); float roughnessSquared = roughness * roughness; @@ -442,37 +454,39 @@ vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao) /* Accumulate light from all sources until accumulator is full. Then apply Occlusion and BRDF. */ vec4 spec_accum = vec4(0.0); - /* Planar Reflections */ - for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999; ++i) { - PlanarData pd = planars_data[i]; + if (!(ssrToggle && ssr_id == outputSsrId)) { + /* Planar Reflections */ + for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999; ++i) { + PlanarData pd = planars_data[i]; - float fade = probe_attenuation_planar(pd, worldPosition, N); + float fade = probe_attenuation_planar(pd, worldPosition, N, roughness); - if (fade > 0.0) { - vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, cameraPos, roughness, fade); - accumulate_light(spec, fade, spec_accum); + if (fade > 0.0) { + vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, roughness, fade); + accumulate_light(spec, fade, spec_accum); + } } - } - /* Specular probes */ - vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared); + /* Specular probes */ + vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared); - /* Starts at 1 because 0 is world probe */ - for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) { - CubeData cd = probes_data[i]; + /* Starts at 1 because 0 is world probe */ + for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) { + CubeData cd = probes_data[i]; - float fade = probe_attenuation_cube(cd, worldPosition); + float fade = probe_attenuation_cube(cd, worldPosition); - if (fade > 0.0) { - vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness); - accumulate_light(spec, fade, spec_accum); + if (fade > 0.0) { + vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness); + accumulate_light(spec, fade, spec_accum); + } } - } - /* World Specular */ - if (spec_accum.a < 0.999) { - vec3 spec = probe_evaluate_world_spec(spec_dir, roughness); - accumulate_light(spec, 1.0, spec_accum); + /* World Specular */ + if (spec_accum.a < 0.999) { + vec3 spec = probe_evaluate_world_spec(spec_dir, roughness); + accumulate_light(spec, 1.0, spec_accum); + } } /* Ambient Occlusion */ @@ -483,7 +497,8 @@ vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao) vec2 uv = lut_coords(dot(N, V), roughness); vec2 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rg; - out_light += spec_accum.rgb * F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness) * float(specToggle); + ssr_spec = F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness); + out_light += spec_accum.rgb * ssr_spec * float(specToggle); return out_light; } diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl new file mode 100644 index 00000000000..855755adfe4 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl @@ -0,0 +1,228 @@ +#define MAX_STEP 256 +#define MAX_REFINE_STEP 32 /* Should be max allowed stride */ + +uniform vec4 ssrParameters; + +uniform sampler2D depthBuffer; +uniform sampler2D maxzBuffer; +uniform sampler2D minzBuffer; +uniform sampler2DArray planarDepth; + +#define ssrQuality ssrParameters.x +#define ssrThickness ssrParameters.y +#define ssrPixelSize ssrParameters.zw + +float sample_depth(vec2 uv, int index, float lod) +{ + if (index > -1) { + return textureLod(planarDepth, vec3(uv, index), 0.0).r; + } + else { + return textureLod(maxzBuffer, uv, lod).r; + } +} + +float sample_minz_depth(vec2 uv, int index) +{ + if (index > -1) { + return textureLod(planarDepth, vec3(uv, index), 0.0).r; + } + else { + return textureLod(minzBuffer, uv, 0.0).r; + } +} + +float sample_maxz_depth(vec2 uv, int index) +{ + if (index > -1) { + return textureLod(planarDepth, vec3(uv, index), 0.0).r; + } + else { + return textureLod(maxzBuffer, uv, 0.0).r; + } +} + +vec4 sample_depth_grouped(vec4 uv1, vec4 uv2, int index, float lod) +{ + vec4 depths; + if (index > -1) { + depths.x = textureLod(planarDepth, vec3(uv1.xy, index), 0.0).r; + depths.y = textureLod(planarDepth, vec3(uv1.zw, index), 0.0).r; + depths.z = textureLod(planarDepth, vec3(uv2.xy, index), 0.0).r; + depths.w = textureLod(planarDepth, vec3(uv2.zw, index), 0.0).r; + } + else { + depths.x = textureLod(maxzBuffer, uv1.xy, lod).r; + depths.y = textureLod(maxzBuffer, uv1.zw, lod).r; + depths.z = textureLod(maxzBuffer, uv2.xy, lod).r; + depths.w = textureLod(maxzBuffer, uv2.zw, lod).r; + } + return depths; +} + +float refine_isect(float prev_delta, float curr_delta) +{ + /** + * Simplification of 2D intersection : + * r0 = (0.0, prev_ss_ray.z); + * r1 = (1.0, curr_ss_ray.z); + * d0 = (0.0, prev_hit_depth_sample); + * d1 = (1.0, curr_hit_depth_sample); + * vec2 r = r1 - r0; + * vec2 d = d1 - d0; + * vec2 isect = ((d * cross(r1, r0)) - (r * cross(d1, d0))) / cross(r,d); + * + * We only want isect.x to know how much stride we need. So it simplifies : + * + * isect_x = (cross(r1, r0) - cross(d1, d0)) / cross(r,d); + * isect_x = (prev_ss_ray.z - prev_hit_depth_sample.z) / cross(r,d); + */ + return saturate(prev_delta / (prev_delta - curr_delta)); +} + +void prepare_raycast(vec3 ray_origin, vec3 ray_dir, out vec4 ss_step, out vec4 ss_ray, out float max_time) +{ + /* Negate the ray direction if it goes towards the camera. + * This way we don't need to care if the projected point + * is behind the near plane. */ + float z_sign = -sign(ray_dir.z); + vec3 ray_end = z_sign * ray_dir * 1e16 + ray_origin; + + /* Project into screen space. */ + vec3 ss_start = project_point(ProjectionMatrix, ray_origin); + vec3 ss_end = project_point(ProjectionMatrix, ray_end); + /* 4th component is current stride */ + ss_step = vec4(z_sign * normalize(ss_end - ss_start), 1.0); + + /* If the line is degenerate, make it cover at least one pixel + * to not have to handle zero-pixel extent as a special case later */ + ss_step.xy += vec2((dot(ss_step.xy, ss_step.xy) < 0.00001) ? 0.001 : 0.0); + + /* Make ss_step cover one pixel. */ + ss_step.xyz /= max(abs(ss_step.x), abs(ss_step.y)); + ss_step.xyz *= ((abs(ss_step.x) > abs(ss_step.y)) ? ssrPixelSize.x : ssrPixelSize.y); + + /* Clipping to frustum sides. */ + max_time = line_unit_box_intersect_dist(ss_start, ss_step.xyz) - 1.0; + + /* Convert to texture coords. Z component included + * since this is how it's stored in the depth buffer. + * 4th component how far we are on the ray */ + ss_ray = vec4(ss_start * 0.5 + 0.5, 0.0); + ss_step.xyz *= 0.5; +} + +/* See times_and_deltas. */ +#define curr_time times_and_deltas.x +#define prev_time times_and_deltas.y +#define curr_delta times_and_deltas.z +#define prev_delta times_and_deltas.w + +// #define GROUPED_FETCHES +/* Return the hit position, and negate the z component (making it positive) if not hit occured. */ +vec3 raycast(int index, vec3 ray_origin, vec3 ray_dir, float ray_jitter, float roughness) +{ + vec4 ss_step, ss_start; + float max_time; + prepare_raycast(ray_origin, ray_dir, ss_step, ss_start, max_time); + +#ifdef GROUPED_FETCHES + ray_jitter *= 0.25; +#endif + /* x : current_time, y: previous_time, z: previous_delta, w: current_delta */ + vec4 times_and_deltas = vec4(0.0, 0.0, 0.001, 0.001); + + float ray_time = 0.0; + float depth_sample; + + float lod_fac = saturate(fast_sqrt(roughness) * 2.0 - 0.4); + bool hit = false; + float iter; + for (iter = 1.0; !hit && (ray_time <= max_time) && (iter < MAX_STEP); iter++) { + /* Minimum stride of 2 because we are using half res minmax zbuffer. */ + float stride = max(1.0, iter * ssrQuality) * 2.0; + float lod = log2(stride * 0.5 * ssrQuality) * lod_fac; + + /* Save previous values. */ + times_and_deltas.xyzw = times_and_deltas.yxwz; + +#ifdef GROUPED_FETCHES + stride *= 4.0; + vec4 jit_stride = mix(vec4(2.0), vec4(stride), vec4(0.0, 0.25, 0.5, 0.75) + ray_jitter); + + vec4 times = vec4(ray_time) + jit_stride; + + vec4 uv1 = ss_start.xyxy + ss_step.xyxy * times.xxyy; + vec4 uv2 = ss_start.xyxy + ss_step.xyxy * times.zzww; + + vec4 depth_samples = sample_depth_grouped(uv1, uv2, index, lod); + + vec4 ray_z = ss_start.zzzz + ss_step.zzzz * times.xyzw; + + vec4 deltas = depth_samples - ray_z; + /* Same as component wise (depth_samples <= ray_z) && (ray_time <= max_time). */ + bvec4 test = equal(step(deltas, vec4(0.0)) * step(times, vec4(max_time)), vec4(1.0)); + hit = any(test); + if (hit) { + vec2 m = vec2(1.0, 0.0); /* Mask */ + + vec4 ret_times_and_deltas = times.wzzz * m.xxyy + deltas.wwwz * m.yyxx; + ret_times_and_deltas = (test.z) ? times.zyyy * m.xxyy + deltas.zzzy * m.yyxx : ret_times_and_deltas; + ret_times_and_deltas = (test.y) ? times.yxxx * m.xxyy + deltas.yyyx * m.yyxx : ret_times_and_deltas; + times_and_deltas = (test.x) ? times.xxxx * m.xyyy + deltas.xxxx * m.yyxy + times_and_deltas.yyww * m.yxyx : ret_times_and_deltas; + + depth_sample = depth_samples.w; + depth_sample = (test.z) ? depth_samples.z : depth_sample; + depth_sample = (test.y) ? depth_samples.y : depth_sample; + depth_sample = (test.x) ? depth_samples.x : depth_sample; + break; + } + curr_time = times.w; + curr_delta = deltas.w; + ray_time += stride; +#else + float jit_stride = mix(2.0, stride, ray_jitter); + + curr_time = ray_time + jit_stride; + vec4 ss_ray = ss_start + ss_step * curr_time; + + depth_sample = sample_depth(ss_ray.xy, index, lod); + + curr_delta = depth_sample - ss_ray.z; + hit = (curr_delta <= 0.0) && (curr_time <= max_time); + + ray_time += stride; +#endif + } + + curr_time = (hit) ? mix(prev_time, curr_time, refine_isect(prev_delta, curr_delta)) : curr_time; + ray_time = (hit) ? curr_time : ray_time; + +#if 0 /* Not needed if using refine_isect() */ + /* Binary search */ + for (float time_step = (curr_time - prev_time) * 0.5; time_step > 1.0; time_step /= 2.0) { + ray_time -= time_step; + vec4 ss_ray = ss_start + ss_step * ray_time; + float depth_sample = sample_maxz_depth(ss_ray.xy, index); + bool is_hit = (depth_sample - ss_ray.z <= 0.0); + ray_time = (is_hit) ? ray_time : ray_time + time_step; + } +#endif + + /* Clip to frustum. */ + ray_time = min(ray_time, max_time - 0.5); + + vec4 ss_ray = ss_start + ss_step * ray_time; + vec3 hit_pos = get_view_space_from_depth(ss_ray.xy, ss_ray.z); + + /* Reject hit if not within threshold. */ + /* TODO do this check while tracing. Potentially higher quality */ + if (hit && (index == -1)) { + float z = get_view_z_from_depth(depth_sample); + hit = hit && ((z - hit_pos.z - ssrThickness) <= ssrThickness); + } + + /* Tag Z if ray failed. */ + hit_pos.z *= (hit) ? 1.0 : -1.0; + return hit_pos; +} diff --git a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl index d9d30c4d9e6..164b6a9940b 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl @@ -15,7 +15,6 @@ flat in int face[]; #ifdef MESH_SHADER in vec3 vNor[]; -in vec3 vNor[]; #endif out vec3 worldPosition; diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index ca6a89f174a..853f2d123eb 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -49,6 +49,8 @@ #include "draw_cache.h" #include "draw_view.h" +#include "draw_manager_profiling.h" + #include "MEM_guardedalloc.h" #include "RE_engine.h" diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index a4753c9b55b..7981b565089 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -1404,7 +1404,7 @@ Gwn_Batch *DRW_cache_lightprobe_grid_get(void) } Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, (6 * 3 + 3) * 2); + GWN_vertbuf_data_alloc(vbo, (6 * 2 + 3) * 2); for (int i = 0; i < 6; ++i) { float tmp_v1[3], tmp_v2[3], tmp_tr[3]; diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index c3d95d700a0..1050594318f 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -84,10 +84,11 @@ void DRW_globals_update(void) /* Grid */ UI_GetThemeColorShade4fv(TH_GRID, 10, ts.colorGrid); /* emphasise division lines lighter instead of darker, if background is darker than grid */ - UI_GetThemeColorShade4fv(TH_GRID, - (ts.colorGrid[0] + ts.colorGrid[1] + ts.colorGrid[2] + 0.12 > - ts.colorBackground[0] + ts.colorBackground[1] + ts.colorBackground[2]) - ? 20 : -10, ts.colorGridEmphasise); + UI_GetThemeColorShade4fv( + TH_GRID, + (ts.colorGrid[0] + ts.colorGrid[1] + ts.colorGrid[2] + 0.12f > + ts.colorBackground[0] + ts.colorBackground[1] + ts.colorBackground[2]) ? + 20 : -10, ts.colorGridEmphasise); /* Grid Axis */ UI_GetThemeColorBlendShade4fv(TH_GRID, TH_AXIS_X, 0.5f, -10, ts.colorGridAxisX); UI_GetThemeColorBlendShade4fv(TH_GRID, TH_AXIS_Y, 0.5f, -10, ts.colorGridAxisY); @@ -102,10 +103,10 @@ void DRW_globals_update(void) ts.sizeLampCircleShadow = ts.sizeLampCircle + U.pixelsize * 3.0f; /* M_SQRT2 to be at least the same size of the old square */ - ts.sizeVertex = ceil(UI_GetThemeValuef(TH_VERTEX_SIZE) * M_SQRT2 / 2.0f); - ts.sizeFaceDot = ceil(UI_GetThemeValuef(TH_FACEDOT_SIZE) * M_SQRT2); + ts.sizeVertex = ceilf(UI_GetThemeValuef(TH_VERTEX_SIZE) * (float)M_SQRT2 / 2.0f); + ts.sizeFaceDot = ceilf(UI_GetThemeValuef(TH_FACEDOT_SIZE) * (float)M_SQRT2); ts.sizeEdge = 1.0f / 2.0f; /* TODO Theme */ - ts.sizeEdgeFix = 0.5f + 2.0f * (2.0f * (MAX2(ts.sizeVertex, ts.sizeEdge)) * M_SQRT1_2); + ts.sizeEdgeFix = 0.5f + 2.0f * (2.0f * (MAX2(ts.sizeVertex, ts.sizeEdge)) * (float)M_SQRT1_2); /* TODO Waiting for notifiers to invalidate cache */ if (globals_ubo) { diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 42a11ebe3e1..df08053c0b5 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -69,8 +69,6 @@ #include "IMB_colormanagement.h" -#include "PIL_time.h" - #include "RE_engine.h" #include "UI_interface.h" @@ -80,6 +78,7 @@ #include "WM_types.h" #include "draw_manager_text.h" +#include "draw_manager_profiling.h" /* only for callbacks */ #include "draw_cache_impl.h" @@ -93,19 +92,63 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" -#define MAX_ATTRIB_NAME 32 -#define MAX_PASS_NAME 32 -#define MAX_CLIP_PLANES 6 /* GL_MAX_CLIP_PLANES is at least 6 */ +/* -------------------------------------------------------------------- */ +/** \name Local Features + * \{ */ + +#define USE_PROFILE + +#ifdef USE_PROFILE +#include "PIL_time.h" + +#define PROFILE_TIMER_FALLOFF 0.1 + +#define PROFILE_START(time_start) \ + double time_start = PIL_check_seconds_timer(); + +#define PROFILE_END_ACCUM(time_accum, time_start) { \ + time_accum += (PIL_check_seconds_timer() - time_start) * 1e3; \ +} ((void)0) + +/* exp average */ +#define PROFILE_END_UPDATE(time_update, time_start) { \ + double _time_delta = (PIL_check_seconds_timer() - time_start) * 1e3; \ + time_update = (time_update * (1.0 - PROFILE_TIMER_FALLOFF)) + \ + (_time_delta * PROFILE_TIMER_FALLOFF); \ +} ((void)0) + +#else + +#define PROFILE_START(time_start) ((void)0) +#define PROFILE_END_ACCUM(time_accum, time_start) ((void)0) +#define PROFILE_END_UPDATE(time_update, time_start) ((void)0) + +#endif /* USE_PROFILE */ + /* Use draw manager to call GPU_select, see: DRW_draw_select_loop */ #define USE_GPU_SELECT +/* Use BLI_memiter */ +#define USE_MEM_ITER + +#ifdef USE_MEM_ITER +#include "BLI_memiter.h" +#endif + #ifdef USE_GPU_SELECT # include "ED_view3d.h" # include "ED_armature.h" # include "GPU_select.h" #endif +/** \} */ + + +#define MAX_ATTRIB_NAME 32 +#define MAX_PASS_NAME 32 +#define MAX_CLIP_PLANES 6 /* GL_MAX_CLIP_PLANES is at least 6 */ + extern char datatoc_gpu_shader_2D_vert_glsl[]; extern char datatoc_gpu_shader_3D_vert_glsl[]; extern char datatoc_gpu_shader_fullscreen_vert_glsl[]; @@ -191,16 +234,13 @@ struct DRWPass { ListBase shgroups; /* DRWShadingGroup */ DRWState state; char name[MAX_PASS_NAME]; - /* use two query to not stall the cpu waiting for queries to complete */ - unsigned int timer_queries[2]; - /* alternate between front and back query */ - unsigned int front_idx; - unsigned int back_idx; - bool wasdrawn; /* if it was drawn during this frame */ }; typedef struct DRWCallHeader { +#ifndef USE_MEM_ITER void *next, *prev; +#endif + #ifdef USE_GPU_SELECT int select_id; #endif @@ -237,7 +277,14 @@ struct DRWShadingGroup { GPUShader *shader; /* Shader to bind */ DRWInterface *interface; /* Uniforms pointers */ - ListBase calls; /* DRWCall or DRWCallDynamic depending of type */ + + /* DRWCall or DRWCallDynamic depending of type */ +#ifdef USE_MEM_ITER + BLI_memiter *calls; +#else + ListBase calls; +#endif + DRWState state_extra; /* State changes for this batch only (or'd with the pass's state) */ DRWState state_extra_disable; /* State changes for this batch only (and'd with the pass's state) */ int type; @@ -699,6 +746,7 @@ static void DRW_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRW DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass) { DRWShadingGroup *shgroup = MEM_mallocN(sizeof(DRWShadingGroup), "DRWShadingGroup"); + BLI_addtail(&pass->shgroups, shgroup); shgroup->type = DRW_SHG_NORMAL; shgroup->shader = shader; @@ -708,8 +756,11 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass) shgroup->batch_geom = NULL; shgroup->instance_geom = NULL; - BLI_addtail(&pass->shgroups, shgroup); +#ifdef USE_MEM_ITER + shgroup->calls = BLI_memiter_create(BLI_MEMITER_DEFAULT_SIZE); +#else BLI_listbase_clear(&shgroup->calls); +#endif #ifdef USE_GPU_SELECT shgroup->pass_parent = pass; @@ -845,7 +896,12 @@ DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DR void DRW_shgroup_free(struct DRWShadingGroup *shgroup) { +#ifdef USE_MEM_ITER + BLI_memiter_destroy(shgroup->calls); +#else BLI_freelistN(&shgroup->calls); +#endif + BLI_freelistN(&shgroup->interface->uniforms); BLI_freelistN(&shgroup->interface->attribs); @@ -872,7 +928,14 @@ void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obm { BLI_assert(geom != NULL); - DRWCall *call = MEM_callocN(sizeof(DRWCall), "DRWCall"); + DRWCall *call; + +#ifdef USE_MEM_ITER + call = BLI_memiter_calloc(shgroup->calls, sizeof(DRWCall)); +#else + call = MEM_callocN(sizeof(DRWCall), "DRWCall"); + BLI_addtail(&shgroup->calls, call); +#endif call->head.type = DRW_CALL_SINGLE; #ifdef USE_GPU_SELECT @@ -885,14 +948,22 @@ void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obm call->geometry = geom; - BLI_addtail(&shgroup->calls, call); + + } void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, Object *ob) { BLI_assert(geom != NULL); - DRWCall *call = MEM_callocN(sizeof(DRWCall), "DRWCall"); + DRWCall *call; + +#ifdef USE_MEM_ITER + call = BLI_memiter_calloc(shgroup->calls, sizeof(DRWCall)); +#else + call = MEM_callocN(sizeof(DRWCall), "DRWCall"); + BLI_addtail(&shgroup->calls, call); +#endif call->head.type = DRW_CALL_SINGLE; #ifdef USE_GPU_SELECT @@ -903,7 +974,6 @@ void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, Obje call->geometry = geom; call->ob_data = ob->data; - BLI_addtail(&shgroup->calls, call); } void DRW_shgroup_call_generate_add( @@ -913,7 +983,14 @@ void DRW_shgroup_call_generate_add( { BLI_assert(geometry_fn != NULL); - DRWCallGenerate *call = MEM_callocN(sizeof(DRWCallGenerate), "DRWCallGenerate"); + DRWCallGenerate *call; + +#ifdef USE_MEM_ITER + call = BLI_memiter_calloc(shgroup->calls, sizeof(DRWCallGenerate)); +#else + call = MEM_callocN(sizeof(DRWCallGenerate), "DRWCallGenerate"); + BLI_addtail(&shgroup->calls, call); +#endif call->head.type = DRW_CALL_GENERATE; #ifdef USE_GPU_SELECT @@ -926,8 +1003,6 @@ void DRW_shgroup_call_generate_add( call->geometry_fn = geometry_fn; call->user_data = user_data; - - BLI_addtail(&shgroup->calls, call); } static void sculpt_draw_cb( @@ -957,7 +1032,12 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at #ifdef USE_GPU_SELECT if ((G.f & G_PICKSEL) && (interface->instance_count > 0)) { shgroup = MEM_dupallocN(shgroup); + +#ifdef USE_MEM_ITER + shgroup->calls = BLI_memiter_create(BLI_MEMITER_DEFAULT_SIZE); +#else BLI_listbase_clear(&shgroup->calls); +#endif shgroup->interface = interface = DRW_interface_duplicate(interface); interface->instance_count = 0; @@ -969,7 +1049,16 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at unsigned int data_size = sizeof(void *) * interface->attribs_count; int size = sizeof(DRWCallDynamic) + data_size; - DRWCallDynamic *call = MEM_callocN(size, "DRWCallDynamic"); + DRWCallDynamic *call; + +#ifdef USE_MEM_ITER + call = BLI_memiter_alloc(shgroup->calls, size); +#else + call = MEM_mallocN(size, "DRWCallDynamic"); + BLI_addtail(&shgroup->calls, call); +#endif + + memset(call, 0x0, sizeof(DRWCallDynamic)); BLI_assert(attr_len == interface->attribs_count); UNUSED_VARS_NDEBUG(attr_len); @@ -984,8 +1073,6 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at } interface->instance_count += 1; - - BLI_addtail(&shgroup->calls, call); } /* Used for instancing with no attributes */ @@ -1151,7 +1238,14 @@ static void shgroup_dynamic_batch(DRWShadingGroup *shgroup) GWN_vertbuf_data_alloc(vbo, nbr); int j = 0; - for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->head.next, j++) { +#ifdef USE_MEM_ITER + BLI_memiter_handle calls_iter; + BLI_memiter_iter_init(shgroup->calls, &calls_iter); + for (DRWCallDynamic *call; (call = BLI_memiter_iter_step(&calls_iter)); j++) +#else + for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->head.next, j++) +#endif + { int i = 0; for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next, i++) { GWN_vertbuf_attr_set(vbo, attrib->format_id, j, call->data[i]); @@ -1199,7 +1293,14 @@ static void shgroup_dynamic_instance(DRWShadingGroup *shgroup) buffer_size = sizeof(float) * interface->attribs_stride * interface->instance_count; float *data = MEM_mallocN(buffer_size, "Instance VBO data"); - for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->head.next) { +#ifdef USE_MEM_ITER + BLI_memiter_handle calls_iter; + BLI_memiter_iter_init(shgroup->calls, &calls_iter); + for (DRWCallDynamic *call; (call = BLI_memiter_iter_step(&calls_iter)); ) +#else + for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->head.next) +#endif + { for (int j = 0; j < interface->attribs_count; ++j) { memcpy(data + offset, call->data[j], sizeof(float) * interface->attribs_size[j]); offset += interface->attribs_size[j]; @@ -1260,7 +1361,6 @@ void DRW_pass_free(DRWPass *pass) DRW_shgroup_free(shgroup); } - glDeleteQueries(2, pass->timer_queries); BLI_freelistN(&pass->shgroups); } @@ -1278,11 +1378,21 @@ typedef struct ZSortData { static int pass_shgroup_dist_sort(void *thunk, const void *a, const void *b) { + const ZSortData *zsortdata = (ZSortData *)thunk; const DRWShadingGroup *shgrp_a = (const DRWShadingGroup *)a; const DRWShadingGroup *shgrp_b = (const DRWShadingGroup *)b; - const DRWCall *call_a = (DRWCall *)(shgrp_a)->calls.first; - const DRWCall *call_b = (DRWCall *)(shgrp_b)->calls.first; - const ZSortData *zsortdata = (ZSortData *)thunk; + + const DRWCall *call_a; + const DRWCall *call_b; + +#ifdef USE_MEM_ITER + call_a = BLI_memiter_elem_first(shgrp_a->calls); + call_b = BLI_memiter_elem_first(shgrp_b->calls); +#else + call_a = shgrp_a->calls.first; + call_b = shgrp_b->calls.first; +#endif + float tmp[3]; sub_v3_v3v3(tmp, zsortdata->origin, call_a->obmat[3]); @@ -1829,11 +1939,24 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) if ((G.f & G_PICKSEL) && (_call)) { \ GPU_select_load_id((_call)->head.select_id); \ } ((void)0) + +#ifdef USE_MEM_ITER +# define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_call_ls) \ + if (G.f & G_PICKSEL) { \ + DRWCall *call_test = BLI_memiter_elem_first(*(_call_ls)); \ + if (call_test != NULL) { \ + BLI_assert(BLI_memiter_count(*(_call_ls)) == 1); \ + GPU_select_load_id(call_test->head.select_id); \ + } \ + } ((void)0) +#else # define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_call_ls) \ if ((G.f & G_PICKSEL) && (_call_ls)->first) { \ BLI_assert(BLI_listbase_is_single(_call_ls)); \ GPU_select_load_id(((DRWCall *)(_call_ls)->first)->head.select_id); \ } ((void)0) +#endif + #else # define GPU_SELECT_LOAD_IF_PICKSEL(call) # define GPU_SELECT_LOAD_IF_PICKSEL_LIST(call) @@ -1860,7 +1983,14 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) } } else { - for (DRWCall *call = shgroup->calls.first; call; call = call->head.next) { +#ifdef USE_MEM_ITER + BLI_memiter_handle calls_iter; + BLI_memiter_iter_init(shgroup->calls, &calls_iter); + for (DRWCall *call; (call = BLI_memiter_iter_step(&calls_iter)); ) +#else + for (DRWCall *call = shgroup->calls.first; call; call = call->head.next) +#endif + { bool neg_scale = is_negative_m4(call->obmat); /* Negative scale objects */ @@ -1900,28 +2030,7 @@ static void DRW_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWSha DRW_state_set(pass->state); BLI_listbase_clear(&DST.bound_texs); - /* Init Timer queries */ - if (pass->timer_queries[0] == 0) { - pass->front_idx = 0; - pass->back_idx = 1; - - glGenQueries(2, pass->timer_queries); - - /* dummy query, avoid gl error */ - glBeginQuery(GL_TIME_ELAPSED, pass->timer_queries[pass->front_idx]); - glEndQuery(GL_TIME_ELAPSED); - } - else { - /* swap indices */ - unsigned int tmp = pass->back_idx; - pass->back_idx = pass->front_idx; - pass->front_idx = tmp; - } - - if (!pass->wasdrawn) { - /* issue query for the next frame */ - glBeginQuery(GL_TIME_ELAPSED, pass->timer_queries[pass->back_idx]); - } + DRW_stats_query_start(pass->name); for (DRWShadingGroup *shgroup = start_group; shgroup; shgroup = shgroup->next) { draw_shgroup(shgroup, pass->state); @@ -1943,11 +2052,7 @@ static void DRW_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWSha DST.shader = NULL; } - if (!pass->wasdrawn) { - glEndQuery(GL_TIME_ELAPSED); - } - - pass->wasdrawn = true; + DRW_stats_query_end(); } void DRW_draw_pass(DRWPass *pass) @@ -2542,21 +2647,18 @@ void DRW_lamp_engine_data_free(LampEngineData *led) /** \name Rendering (DRW_engines) * \{ */ -#define TIMER_FALLOFF 0.1f - static void DRW_engines_init(void) { for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { DrawEngineType *engine = link->data; ViewportEngineData *data = DRW_viewport_engine_data_get(engine); - double stime = PIL_check_seconds_timer(); + PROFILE_START(stime); if (engine->engine_init) { engine->engine_init(data); } - double ftime = (PIL_check_seconds_timer() - stime) * 1e3; - data->init_time = data->init_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */ + PROFILE_END_UPDATE(data->init_time, stime); } } @@ -2574,14 +2676,13 @@ static void DRW_engines_cache_init(void) DST.text_store_p = &data->text_draw_cache; } - double stime = PIL_check_seconds_timer(); + PROFILE_START(stime); data->cache_time = 0.0; if (engine->cache_init) { engine->cache_init(data); } - - data->cache_time += (PIL_check_seconds_timer() - stime) * 1e3; + PROFILE_END_ACCUM(data->cache_time, stime); } } @@ -2590,13 +2691,13 @@ static void DRW_engines_cache_populate(Object *ob) for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { DrawEngineType *engine = link->data; ViewportEngineData *data = DRW_viewport_engine_data_get(engine); - double stime = PIL_check_seconds_timer(); + PROFILE_START(stime); if (engine->cache_populate) { engine->cache_populate(data, ob); } - data->cache_time += (PIL_check_seconds_timer() - stime) * 1e3; + PROFILE_END_ACCUM(data->cache_time, stime); } } @@ -2605,13 +2706,13 @@ static void DRW_engines_cache_finish(void) for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { DrawEngineType *engine = link->data; ViewportEngineData *data = DRW_viewport_engine_data_get(engine); - double stime = PIL_check_seconds_timer(); + PROFILE_START(stime); if (engine->cache_finish) { engine->cache_finish(data); } - data->cache_time += (PIL_check_seconds_timer() - stime) * 1e3; + PROFILE_END_ACCUM(data->cache_time, stime); } } @@ -2620,15 +2721,17 @@ static void DRW_engines_draw_background(void) for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { DrawEngineType *engine = link->data; ViewportEngineData *data = DRW_viewport_engine_data_get(engine); - double stime = PIL_check_seconds_timer(); if (engine->draw_background) { + PROFILE_START(stime); + + DRW_stats_group_start(engine->idname); engine->draw_background(data); + DRW_stats_group_end(); + + PROFILE_END_UPDATE(data->background_time, stime); return; } - - double ftime = (PIL_check_seconds_timer() - stime) * 1e3; - data->background_time = data->background_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */ } /* No draw_background found, doing default background */ @@ -2640,14 +2743,15 @@ static void DRW_engines_draw_scene(void) for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { DrawEngineType *engine = link->data; ViewportEngineData *data = DRW_viewport_engine_data_get(engine); - double stime = PIL_check_seconds_timer(); + PROFILE_START(stime); if (engine->draw_scene) { + DRW_stats_group_start(engine->idname); engine->draw_scene(data); + DRW_stats_group_end(); } - double ftime = (PIL_check_seconds_timer() - stime) * 1e3; - data->render_time = data->render_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */ + PROFILE_END_UPDATE(data->render_time, stime); } } @@ -2656,14 +2760,13 @@ static void DRW_engines_draw_text(void) for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { DrawEngineType *engine = link->data; ViewportEngineData *data = DRW_viewport_engine_data_get(engine); - double stime = PIL_check_seconds_timer(); + PROFILE_START(stime); if (data->text_draw_cache) { DRW_text_cache_draw(data->text_draw_cache, DST.draw_ctx.v3d, DST.draw_ctx.ar, false); } - double ftime = (PIL_check_seconds_timer() - stime) * 1e3; - data->render_time = data->render_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */ + PROFILE_END_UPDATE(data->render_time, stime); } } @@ -2880,7 +2983,7 @@ static unsigned int DRW_engines_get_hash(void) static void draw_stat(rcti *rect, int u, int v, const char *txt, const int size) { BLF_draw_default_ascii(rect->xmin + (1 + u * 5) * U.widget_unit, - rect->ymax - (3 + v++) * U.widget_unit, 0.0f, + rect->ymax - (3 + v) * U.widget_unit, 0.0f, txt, size); } @@ -2971,66 +3074,32 @@ static void DRW_debug_gpu_stats(void) UI_FontThemeColor(BLF_default(), TH_TEXT_HI); - char time_to_txt[16]; - char pass_name[MAX_PASS_NAME + 16]; int v = BLI_listbase_count(&DST.enabled_engines) + 3; - GLuint64 tot_time = 0; - - if (G.debug_value > 666) { - for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { - GLuint64 engine_time = 0; - DrawEngineType *engine = link->data; - ViewportEngineData *data = DRW_viewport_engine_data_get(engine); - int vsta = v; - - draw_stat(&rect, 0, v, engine->idname, sizeof(engine->idname)); - v++; - for (int i = 0; i < engine->vedata_size->psl_len; ++i) { - DRWPass *pass = data->psl->passes[i]; - if (pass != NULL && pass->wasdrawn) { - GLuint64 time; - glGetQueryObjectui64v(pass->timer_queries[pass->front_idx], GL_QUERY_RESULT, &time); - - sprintf(pass_name, " |--> %s", pass->name); - draw_stat(&rect, 0, v, pass_name, sizeof(pass_name)); - - sprintf(time_to_txt, "%.2fms", time / 1000000.0); - engine_time += time; - tot_time += time; - - draw_stat(&rect, 2, v++, time_to_txt, sizeof(time_to_txt)); - - pass->wasdrawn = false; - } - } - /* engine total time */ - sprintf(time_to_txt, "%.2fms", engine_time / 1000000.0); - draw_stat(&rect, 2, vsta, time_to_txt, sizeof(time_to_txt)); - v++; - } - - sprintf(pass_name, "Total GPU time %.2fms (%.1f fps)", tot_time / 1000000.0, 1000000000.0 / tot_time); - draw_stat(&rect, 0, v++, pass_name, sizeof(pass_name)); - v++; - } + char stat_string[32]; /* Memory Stats */ unsigned int tex_mem = GPU_texture_memory_usage_get(); unsigned int vbo_mem = GWN_vertbuf_get_memory_usage(); - sprintf(pass_name, "GPU Memory"); - draw_stat(&rect, 0, v, pass_name, sizeof(pass_name)); - sprintf(pass_name, "%.2fMB", (float)(tex_mem + vbo_mem) / 1000000.0); - draw_stat(&rect, 1, v++, pass_name, sizeof(pass_name)); - sprintf(pass_name, " |--> Textures"); - draw_stat(&rect, 0, v, pass_name, sizeof(pass_name)); - sprintf(pass_name, "%.2fMB", (float)tex_mem / 1000000.0); - draw_stat(&rect, 1, v++, pass_name, sizeof(pass_name)); - sprintf(pass_name, " |--> Meshes"); - draw_stat(&rect, 0, v, pass_name, sizeof(pass_name)); - sprintf(pass_name, "%.2fMB", (float)vbo_mem / 1000000.0); - draw_stat(&rect, 1, v++, pass_name, sizeof(pass_name)); + sprintf(stat_string, "GPU Memory"); + draw_stat(&rect, 0, v, stat_string, sizeof(stat_string)); + sprintf(stat_string, "%.2fMB", (double)(tex_mem + vbo_mem) / 1000000.0); + draw_stat(&rect, 1, v++, stat_string, sizeof(stat_string)); + sprintf(stat_string, " |--> Textures"); + draw_stat(&rect, 0, v, stat_string, sizeof(stat_string)); + sprintf(stat_string, "%.2fMB", (double)tex_mem / 1000000.0); + draw_stat(&rect, 1, v++, stat_string, sizeof(stat_string)); + sprintf(stat_string, " |--> Meshes"); + draw_stat(&rect, 0, v, stat_string, sizeof(stat_string)); + sprintf(stat_string, "%.2fMB", (double)vbo_mem / 1000000.0); + draw_stat(&rect, 1, v++, stat_string, sizeof(stat_string)); + + /* Pre offset for stats_draw */ + rect.ymax -= (3 + ++v) * U.widget_unit; + + /* Rendering Stats */ + DRW_stats_draw(&rect); } @@ -3109,6 +3178,8 @@ void DRW_draw_render_loop_ex( DRW_engines_cache_finish(); } + DRW_stats_begin(); + /* Start Drawing */ DRW_state_reset(); DRW_engines_draw_background(); @@ -3132,13 +3203,14 @@ void DRW_draw_render_loop_ex( if (DST.draw_ctx.evil_C) { /* needed so manipulator isn't obscured */ glDisable(GL_DEPTH_TEST); - DRW_draw_manipulator(); glEnable(GL_DEPTH_TEST); DRW_draw_region_info(); } + DRW_stats_reset(); + if (G.debug_value > 20) { DRW_debug_cpu_stats(); DRW_debug_gpu_stats(); @@ -3565,6 +3637,7 @@ extern struct GPUTexture *globals_ramp; /* draw_common.c */ void DRW_engines_free(void) { DRW_shape_cache_free(); + DRW_stats_free(); DrawEngineType *next; for (DrawEngineType *type = DRW_engines.first; type; type = next) { diff --git a/source/blender/draw/intern/draw_manager_profiling.c b/source/blender/draw/intern/draw_manager_profiling.c new file mode 100644 index 00000000000..bca9e50da99 --- /dev/null +++ b/source/blender/draw/intern/draw_manager_profiling.c @@ -0,0 +1,242 @@ +/* + * Copyright 2016, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Blender Institute + * + */ + +/** \file draw_manager_profiling.c + * \ingroup draw + */ + +#include "BLI_rect.h" +#include "BLI_string.h" + +#include "BKE_global.h" + +#include "BLF_api.h" + +#include "MEM_guardedalloc.h" + +#include "GPU_glew.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "draw_manager_profiling.h" + +#define MAX_TIMER_NAME 32 +#define MAX_NESTED_TIMER 8 +#define CHUNK_SIZE 8 +#define GPU_TIMER_FALLOFF 0.1 + +typedef struct DRWTimer { + GLuint query[2]; + GLuint64 time_average; + char name[MAX_TIMER_NAME]; + int lvl; /* Hierarchy level for nested timer. */ + bool is_query; /* Does this timer actually perform queries or is it just a group. */ +} DRWTimer; + +static struct DRWTimerPool { + DRWTimer *timers; + int chunk_count; /* Number of chunk allocated. */ + int timer_count; /* chunk_count * CHUNK_SIZE */ + int timer_increment; /* Keep track of where we are in the stack. */ + int end_increment; /* Keep track of bad usage. */ + bool is_recording; /* Are we in the render loop? */ + bool is_querying; /* Keep track of bad usage. */ +} DTP = {NULL}; + +void DRW_stats_free(void) +{ + if (DTP.timers != NULL) { + for (int i = 0; i < DTP.timer_count; ++i) { + DRWTimer *timer = &DTP.timers[i]; + glDeleteQueries(2, timer->query); + } + MEM_freeN(DTP.timers); + DTP.timers = NULL; + } +} + +void DRW_stats_begin(void) +{ + if (G.debug_value > 20) { + DTP.is_recording = true; + } + + if (DTP.is_recording && DTP.timers == NULL) { + DTP.chunk_count = 1; + DTP.timer_count = DTP.chunk_count * CHUNK_SIZE; + DTP.timers = MEM_callocN(sizeof(DRWTimer) * DTP.timer_count, "DRWTimer stack"); + } + else if(!DTP.is_recording && DTP.timers != NULL) { + DRW_stats_free(); + } + + DTP.is_querying = false; + DTP.timer_increment = 0; + DTP.end_increment = 0; +} + +static DRWTimer *drw_stats_timer_get(void) +{ + if (UNLIKELY(DTP.timer_increment >= DTP.timer_count)) { + /* Resize the stack. */ + DTP.chunk_count++; + DTP.timer_count = DTP.chunk_count * CHUNK_SIZE; + DTP.timers = MEM_recallocN(DTP.timers, sizeof(DRWTimer) * DTP.timer_count); + } + + return &DTP.timers[DTP.timer_increment++]; +} + +static void drw_stats_timer_start_ex(const char *name, const bool is_query) +{ + if (DTP.is_recording) { + DRWTimer *timer = drw_stats_timer_get(); + BLI_strncpy(timer->name, name, MAX_TIMER_NAME); + timer->lvl = DTP.timer_increment - DTP.end_increment - 1; + timer->is_query = is_query; + + /* Queries cannot be nested or interleaved. */ + BLI_assert(!DTP.is_querying); + if (timer->is_query) { + if (timer->query[0] == 0) { + glGenQueries(1, timer->query); + } + + /* Issue query for the next frame */ + glBeginQuery(GL_TIME_ELAPSED, timer->query[0]); + DTP.is_querying = true; + } + } +} + +/* Use this to group the queries. It does NOT keep track + * of the time, it only sum what the queries inside it. */ +void DRW_stats_group_start(const char *name) +{ + drw_stats_timer_start_ex(name, false); +} + +void DRW_stats_group_end(void) +{ + if (DTP.is_recording) { + BLI_assert(!DTP.is_querying); + DTP.end_increment++; + } +} + +/* NOTE: Only call this when no sub timer will be called. */ +void DRW_stats_query_start(const char *name) +{ + drw_stats_timer_start_ex(name, true); +} + +void DRW_stats_query_end(void) +{ + if (DTP.is_recording) { + DTP.end_increment++; + BLI_assert(DTP.is_querying); + glEndQuery(GL_TIME_ELAPSED); + DTP.is_querying = false; + } +} + +void DRW_stats_reset(void) +{ + BLI_assert((DTP.timer_increment - DTP.end_increment) <= 0 && "You forgot a DRW_stats_group/query_end somewhere!"); + BLI_assert((DTP.timer_increment - DTP.end_increment) >= 0 && "You forgot a DRW_stats_group/query_start somewhere!"); + + if (DTP.is_recording) { + GLuint64 lvl_time[MAX_NESTED_TIMER] = {0}; + + /* Swap queries for the next frame and sum up each lvl time. */ + for (int i = DTP.timer_increment - 1; i >= 0; --i) { + DRWTimer *timer = &DTP.timers[i]; + SWAP(GLuint, timer->query[0], timer->query[1]); + + BLI_assert(timer->lvl < MAX_NESTED_TIMER); + + if (timer->is_query) { + GLuint64 time; + if (timer->query[0] != 0) { + glGetQueryObjectui64v(timer->query[0], GL_QUERY_RESULT, &time); + } + else { + time = 1000000000; /* 1ms default */ + } + + timer->time_average = timer->time_average * (1.0 - GPU_TIMER_FALLOFF) + time * GPU_TIMER_FALLOFF; + timer->time_average = MIN2(timer->time_average, 1000000000); + } + else { + timer->time_average = lvl_time[timer->lvl + 1]; + lvl_time[timer->lvl + 1] = 0; + } + + lvl_time[timer->lvl] += timer->time_average; + } + + DTP.is_recording = false; + } +} + +void DRW_stats_draw(rcti *rect) +{ + char stat_string[64]; + int lvl_index[MAX_NESTED_TIMER]; + int v = 0; + + BLI_snprintf(stat_string, sizeof(stat_string), "GPU Render Stats"); + BLF_draw_default_ascii(rect->xmin + 1 * U.widget_unit, rect->ymax - v++ * U.widget_unit, 0.0f, stat_string, sizeof(stat_string)); + + for (int i = 0; i < DTP.timer_increment; ++i) { + double time_ms, time_percent; + DRWTimer *timer = &DTP.timers[i]; + DRWTimer *timer_parent = (timer->lvl > 0) ? &DTP.timers[lvl_index[timer->lvl - 1]] : NULL; + + /* Only display a number of lvl at a time */ + if ((G.debug_value - 21) < timer->lvl) continue; + + BLI_assert(timer->lvl < MAX_NESTED_TIMER); + lvl_index[timer->lvl] = i; + + time_ms = timer->time_average / 1000000.0; + + if (timer_parent != NULL) { + time_percent = ((double)timer->time_average / (double)timer_parent->time_average) * 100.0; + } + else { + time_percent = 100.0; + } + + /* avoid very long number */ + time_ms = MIN2(time_ms, 999.0); + time_percent = MIN2(time_percent, 100.0); + + BLI_snprintf(stat_string, sizeof(stat_string), "%.2fms", time_ms); + BLF_draw_default_ascii(rect->xmin + 1 * U.widget_unit, rect->ymax - v * U.widget_unit, 0.0f, stat_string, sizeof(stat_string)); + BLI_snprintf(stat_string, sizeof(stat_string), "%.0f", time_percent); + BLF_draw_default_ascii(rect->xmin + 4 * U.widget_unit, rect->ymax - v * U.widget_unit, 0.0f, stat_string, sizeof(stat_string)); + BLI_snprintf(stat_string, sizeof(stat_string), "%s", timer->name); + BLF_draw_default_ascii(rect->xmin + (6 + timer->lvl) * U.widget_unit, rect->ymax - v * U.widget_unit, 0.0f, stat_string, sizeof(stat_string)); + v++; + } +}
\ No newline at end of file diff --git a/source/blender/draw/intern/draw_manager_profiling.h b/source/blender/draw/intern/draw_manager_profiling.h new file mode 100644 index 00000000000..233cd3878d2 --- /dev/null +++ b/source/blender/draw/intern/draw_manager_profiling.h @@ -0,0 +1,43 @@ +/* + * Copyright 2016, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Blender Institute + * + */ + +/** \file draw_manager_profiling.h + * \ingroup draw + */ + +#ifndef __DRAW_MANAGER_PROFILING_H__ +#define __DRAW_MANAGER_PROFILING_H__ + +struct rcti; + +void DRW_stats_free(void); +void DRW_stats_begin(void); +void DRW_stats_reset(void); + +void DRW_stats_group_start(const char *name); +void DRW_stats_group_end(void); + +void DRW_stats_query_start(const char *name); +void DRW_stats_query_end(void); + +void DRW_stats_draw(rcti *rect); + +#endif /* __DRAW_MANAGER_PROFILING_H__ */ diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 37c44f33915..67bb781562e 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -680,7 +680,7 @@ void DRW_draw_cursor(void) immAttrib3fv(wpos, co); for (int i = 0; i < segments; ++i) { - float angle = 2 * M_PI * ((float)i / (float)segments); + float angle = (float)(2 * M_PI) * ((float)i / (float)segments); float x = f10 * cosf(angle); float y = f10 * sinf(angle); @@ -728,5 +728,29 @@ void DRW_draw_manipulator(void) /* draw depth culled manipulators - manipulators need to be updated *after* view matrix was set up */ /* TODO depth culling manipulators is not yet supported, just drawing _3D here, should * later become _IN_SCENE (and draw _3D separate) */ - WM_manipulatormap_draw(ar->manipulator_map, draw_ctx->evil_C, WM_MANIPULATORMAP_DRAWSTEP_3D); + WM_manipulatormap_draw( + ar->manipulator_map, draw_ctx->evil_C, + WM_MANIPULATORMAP_DRAWSTEP_3D); + + /* We may want to split this into a separate pass. + * or maintain a stage in the draw manager where all pixel-space drawing happens. */ + { + float original_proj[4][4]; + gpuGetProjectionMatrix(original_proj); + wmOrtho2_region_pixelspace(ar); + + gpuPushMatrix(); + gpuLoadIdentity(); + + glDepthMask(GL_FALSE); + + WM_manipulatormap_draw( + ar->manipulator_map, draw_ctx->evil_C, + WM_MANIPULATORMAP_DRAWSTEP_2D); + + glDepthMask(GL_TRUE); + + gpuPopMatrix(); + gpuLoadProjectionMatrix(original_proj); + } } diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 7b255a65ea3..26d67a28226 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -496,7 +496,7 @@ static void OBJECT_engine_init(void *vedata) e_data.grid_settings[1] = grid_res; /* gridResolution */ e_data.grid_settings[2] = grid_scale; /* gridScale */ e_data.grid_settings[3] = v3d->gridsubdiv; /* gridSubdiv */ - e_data.grid_settings[4] = (v3d->gridsubdiv > 1) ? 1.0f / log(v3d->gridsubdiv) : 0.0; /* 1/log(gridSubdiv) */ + e_data.grid_settings[4] = (v3d->gridsubdiv > 1) ? 1.0f / logf(v3d->gridsubdiv) : 0.0f; /* 1/log(gridSubdiv) */ } } @@ -1147,7 +1147,7 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl size[0] = size[1] = blend; size[2] = 1.0f; size_to_mat4(sizemat, size); translate_m4(sizemat, 0.0f, 0.0f, -1.0f); - rotate_m4(sizemat, 'X', M_PI / 2.0f); + rotate_m4(sizemat, 'X', (float)(M_PI / 2)); mul_m4_m4m4(spotblendmat, shapemat, sizemat); if (la->mode & LA_SQUARE) { @@ -1813,6 +1813,7 @@ static void OBJECT_draw_scene(void *vedata) float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f}; if (DRW_state_is_fbo()) { + DRW_stats_group_start("Outlines"); /* attach temp textures */ DRW_framebuffer_texture_attach(fbl->outlines, e_data.outlines_depth_tx, 0, 0); DRW_framebuffer_texture_attach(fbl->outlines, e_data.outlines_color_tx, 0, 0); @@ -1823,6 +1824,7 @@ static void OBJECT_draw_scene(void *vedata) DRW_framebuffer_clear(true, true, false, clearcol, 1.0f); DRW_draw_pass(psl->outlines); + /* detach textures */ DRW_framebuffer_texture_detach(e_data.outlines_depth_tx); @@ -1855,6 +1857,7 @@ static void OBJECT_draw_scene(void *vedata) /* restore main framebuffer */ DRW_framebuffer_bind(dfbl->default_fb); + DRW_stats_group_end(); } /* This needs to be drawn after the oultine */ diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c index a3f29b5bb8f..7d2c96dc8de 100644 --- a/source/blender/draw/modes/sculpt_mode.c +++ b/source/blender/draw/modes/sculpt_mode.c @@ -33,6 +33,8 @@ #include "BKE_pbvh.h" #include "BKE_paint.h" +#include "DEG_depsgraph.h" + /* If builtin shaders are needed */ #include "GPU_shader.h" #include "GPU_matrix.h" @@ -191,6 +193,9 @@ static void SCULPT_cache_populate(void *vedata, Object *ob) if (ob->type == OB_MESH) { const DRWContextState *draw_ctx = DRW_context_state_get(); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(draw_ctx->evil_C, &eval_ctx); if (ob->sculpt && (ob == draw_ctx->obact)) { @@ -201,7 +206,7 @@ static void SCULPT_cache_populate(void *vedata, Object *ob) * but this avoids waiting on first stroke) */ Scene *scene = draw_ctx->scene; - BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, false, false); + BKE_sculpt_update_mesh_elements(&eval_ctx, scene, scene->toolsettings->sculpt, ob, false, false); } PBVH *pbvh = ob->sculpt->pbvh; diff --git a/source/blender/draw/modes/shaders/object_grid_frag.glsl b/source/blender/draw/modes/shaders/object_grid_frag.glsl index 0196b1a6f98..61bd4d58a4a 100644 --- a/source/blender/draw/modes/shaders/object_grid_frag.glsl +++ b/source/blender/draw/modes/shaders/object_grid_frag.glsl @@ -75,7 +75,11 @@ vec3 get_floor_pos(vec2 uv, out vec3 wPos) camera_vec = normalize(eye); } - float p = -dot(planeNormal, camera_pos) / dot(planeNormal, camera_vec); + float plane_normal_dot_camera_vec = dot(planeNormal, camera_vec); + float p = -dot(planeNormal, camera_pos); + if (plane_normal_dot_camera_vec != 0) { + p /= plane_normal_dot_camera_vec; + } vec3 plane = camera_pos + camera_vec * p; /* fix residual imprecision */ diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index e563d3f8cf0..dfe7edde337 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -913,7 +913,7 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *even case PADENTER: case LEFTMOUSE: case MIDDLEMOUSE: - if (WM_modal_tweak_exit(event, mm->event_type)) { + if (WM_event_is_modal_tweak_exit(event, mm->event_type)) { ed_marker_move_exit(C, op); WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL); diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 97e5597326e..8d7c32846b3 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -492,7 +492,7 @@ void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, break; default: - size -= 0.5f * key_type; + size -= 0.8f * key_type; } unsigned char fill_col[4]; diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index c1e82583521..071c5fab9d7 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -52,6 +52,7 @@ #include "BKE_deform.h" #include "RNA_access.h" +#include "RNA_enum_types.h" #include "ED_anim_api.h" #include "ED_keyframing.h" diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index d29c0d722b5..82aaee19029 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -1075,10 +1075,11 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou /* for Loc/Rot/Scale and also Color F-Curves, the color of the F-Curve in the Graph Editor, * is determined by the array index for the F-Curve */ - if (ELEM(RNA_property_subtype(prop), PROP_TRANSLATION, PROP_XYZ, PROP_EULER, PROP_COLOR, PROP_COORDS)) { + PropertySubType prop_subtype = RNA_property_subtype(prop); + if (ELEM(prop_subtype, PROP_TRANSLATION, PROP_XYZ, PROP_EULER, PROP_COLOR, PROP_COORDS)) { fcu->color_mode = FCURVE_COLOR_AUTO_RGB; } - else if (RNA_property_subtype(prop), PROP_QUATERNION) { + else if (ELEM(prop_subtype, PROP_QUATERNION)) { fcu->color_mode = FCURVE_COLOR_AUTO_YRGB; } } diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index 17dc8eac38c..bffa58dbf05 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -177,7 +177,7 @@ void *get_nearest_bone(bContext *C, const int xy[2], bool findunsel) rect.xmin = rect.xmax = xy[0]; rect.ymin = rect.ymax = xy[1]; - hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST); + hits = view3d_opengl_select(C, &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST); if (hits > 0) return get_bone_from_selectbuffer(vc.scene, vc.scene_layer->basact, buffer, hits, findunsel, true); @@ -291,7 +291,7 @@ static int selectbuffer_ret_hits_5(unsigned int *buffer, const int hits12, const /* does bones and points */ /* note that BONE ROOT only gets drawn for root bones (or without IK) */ static EditBone *get_nearest_editbonepoint( - ViewContext *vc, const int mval[2], + const bContext *C, ViewContext *vc, const int mval[2], ListBase *edbo, bool findunsel, bool use_cycle, int *r_selmask) { bArmature *arm = (bArmature *)vc->obedit->data; @@ -344,7 +344,7 @@ static EditBone *get_nearest_editbonepoint( view3d_opengl_select_cache_begin(); BLI_rcti_init_pt_radius(&rect, mval, 12); - hits12 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode); + hits12 = view3d_opengl_select(C, vc, buffer, MAXPICKBUF, &rect, select_mode); if (hits12 == 1) { hits = selectbuffer_ret_hits_12(buffer, hits12); goto cache_end; @@ -354,7 +354,7 @@ static EditBone *get_nearest_editbonepoint( offs = 4 * hits12; BLI_rcti_init_pt_radius(&rect, mval, 5); - hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode); + hits5 = view3d_opengl_select(C, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode); if (hits5 == 1) { hits = selectbuffer_ret_hits_5(buffer, hits12, hits5); @@ -492,7 +492,7 @@ bool ED_armature_select_pick(bContext *C, const int mval[2], bool extend, bool d return true; } - nearBone = get_nearest_editbonepoint(&vc, mval, arm->edbo, true, true, &selmask); + nearBone = get_nearest_editbonepoint(C, &vc, mval, arm->edbo, true, true, &selmask); if (nearBone) { if (!extend && !deselect && !toggle) { diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c index e8d41f722d7..3f4a80c9a27 100644 --- a/source/blender/editors/armature/armature_skinning.c +++ b/source/blender/editors/armature/armature_skinning.c @@ -43,12 +43,15 @@ #include "BKE_action.h" #include "BKE_armature.h" +#include "BKE_context.h" #include "BKE_deform.h" #include "BKE_object_deform.h" #include "BKE_report.h" #include "BKE_subsurf.h" #include "BKE_modifier.h" +#include "DEG_depsgraph.h" + #include "ED_armature.h" #include "ED_mesh.h" @@ -247,7 +250,7 @@ static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], i } } -static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, Object *par, +static void add_verts_to_dgroups(ReportList *reports, const bContext *C, Scene *scene, Object *ob, Object *par, int heat, const bool mirror) { /* This functions implements the automatic computation of vertex group @@ -262,6 +265,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, * when parenting, or simply the original mesh coords. */ + EvaluationContext eval_ctx; bArmature *arm = par->data; Bone **bonelist, *bone; bDeformGroup **dgrouplist, **dgroupflip; @@ -275,6 +279,8 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, int wpmode = (ob->mode & OB_MODE_WEIGHT_PAINT); struct { Object *armob; void *list; int heat; } looper_data; + CTX_data_eval_ctx(C, &eval_ctx); + looper_data.armob = par; looper_data.heat = heat; looper_data.list = NULL; @@ -372,7 +378,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, if (wpmode) { /* if in weight paint mode, use final verts from derivedmesh */ - DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + DerivedMesh *dm = mesh_get_derived_final(&eval_ctx, scene, ob, CD_MASK_BAREMESH); if (dm->foreachMappedVert) { mesh_get_mapped_verts_coords(dm, verts, mesh->totvert); @@ -424,7 +430,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, MEM_freeN(verts); } -void create_vgroups_from_armature(ReportList *reports, Scene *scene, Object *ob, Object *par, +void create_vgroups_from_armature(ReportList *reports, const bContext *C, Scene *scene, Object *ob, Object *par, const int mode, const bool mirror) { /* Lets try to create some vertex groups @@ -451,6 +457,6 @@ void create_vgroups_from_armature(ReportList *reports, Scene *scene, Object *ob, * that are populated with the vertices for which the * bone is closest. */ - add_verts_to_dgroups(reports, scene, ob, par, (mode == ARM_GROUPS_AUTO), mirror); + add_verts_to_dgroups(reports, C, scene, ob, par, (mode == ARM_GROUPS_AUTO), mirror); } } diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 20fb7b5e693..cb4d863b7b5 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -1005,7 +1005,7 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S if (ts->snap_mode == SCE_SNAP_MODE_VOLUME) { float size; if (peelObjectsSnapContext( - snap_context, mvalf, + C, snap_context, mvalf, &(const struct SnapObjectParams){ .snap_select = SNAP_NOT_SELECTED, .use_object_edit_cage = false, @@ -1045,7 +1045,7 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S /* try to snap to closer object */ { if (ED_transform_snap_object_project_view3d( - snap_context, + C, snap_context, ts->snap_mode, &(const struct SnapObjectParams){ .snap_select = SNAP_NOT_SELECTED, @@ -1931,7 +1931,7 @@ static bool sk_selectStroke(bContext *C, SK_Sketch *sketch, const int mval[2], c BLI_rcti_init_pt_radius(&rect, mval, 5); - hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST); + hits = view3d_opengl_select(C, &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST); if (hits > 0) { int besthitresult = -1; diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index 736329d29bf..7a8b89899a7 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -96,7 +96,8 @@ void ED_armature_enter_posemode(bContext *C, Base *base) case OB_ARMATURE: ob->restore_mode = ob->mode; ob->mode |= OB_MODE_POSE; - + /* Inform all CoW versions that we changed the mode. */ + DEG_id_tag_update_ex(CTX_data_main(C), &ob->id, DEG_TAG_COPY_ON_WRITE); WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL); break; @@ -115,7 +116,10 @@ void ED_armature_exit_posemode(bContext *C, Base *base) ob->restore_mode = ob->mode; ob->mode &= ~OB_MODE_POSE; - + + /* Inform all CoW versions that we changed the mode. */ + DEG_id_tag_update_ex(CTX_data_main(C), &ob->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL); } } @@ -155,7 +159,7 @@ static bool pose_has_protected_selected(Object *ob, short warn) * * To be called from various tools that do incremental updates */ -void ED_pose_recalculate_paths(Scene *scene, Object *ob) +void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob) { ListBase targets = {NULL, NULL}; @@ -164,7 +168,7 @@ void ED_pose_recalculate_paths(Scene *scene, Object *ob) animviz_get_object_motionpaths(ob, &targets); /* recalculate paths, then free */ - animviz_calc_motionpaths(scene, &targets); + animviz_calc_motionpaths(C, scene, &targets); BLI_freelistN(&targets); } @@ -227,7 +231,7 @@ static int pose_calculate_paths_exec(bContext *C, wmOperator *op) /* calculate the bones that now have motionpaths... */ /* TODO: only make for the selected bones? */ - ED_pose_recalculate_paths(scene, ob); + ED_pose_recalculate_paths(C, scene, ob); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); @@ -283,7 +287,7 @@ static int pose_update_paths_exec(bContext *C, wmOperator *UNUSED(op)) /* calculate the bones that now have motionpaths... */ /* TODO: only make for the selected bones? */ - ED_pose_recalculate_paths(scene, ob); + ED_pose_recalculate_paths(C, scene, ob); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c index 71142c292a6..f11168525c0 100644 --- a/source/blender/editors/armature/pose_lib.c +++ b/source/blender/editors/armature/pose_lib.c @@ -1069,6 +1069,9 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, tPoseLib_PreviewData static void poselib_preview_apply(bContext *C, wmOperator *op) { tPoseLib_PreviewData *pld = (tPoseLib_PreviewData *)op->customdata; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); /* only recalc pose (and its dependencies) if pose has changed */ if (pld->redraw == PL_PREVIEW_REDRAWALL) { @@ -1093,7 +1096,7 @@ static void poselib_preview_apply(bContext *C, wmOperator *op) if ((pld->arm->flag & ARM_DELAYDEFORM) == 0) DEG_id_tag_update(&pld->ob->id, OB_RECALC_DATA); /* sets recalc flags */ else - BKE_pose_where_is(pld->scene, pld->ob); + BKE_pose_where_is(&eval_ctx, pld->scene, pld->ob); } /* do header print - if interactively previewing */ @@ -1584,6 +1587,9 @@ static void poselib_preview_cleanup(bContext *C, wmOperator *op) bArmature *arm = pld->arm; bAction *act = pld->act; TimeMarker *marker = pld->marker; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); /* redraw the header so that it doesn't show any of our stuff anymore */ ED_area_headerprint(pld->sa, NULL); @@ -1601,7 +1607,7 @@ static void poselib_preview_cleanup(bContext *C, wmOperator *op) if ((arm->flag & ARM_DELAYDEFORM) == 0) DEG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ else - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(&eval_ctx, scene, ob); } else if (pld->state == PL_PREVIEW_CONFIRM) { /* tag poses as appropriate */ @@ -1619,7 +1625,7 @@ static void poselib_preview_cleanup(bContext *C, wmOperator *op) //remake_action_ipos(ob->action); } else - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(&eval_ctx, scene, ob); } /* Request final redraw of the view. */ diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c index c2f66db63f8..49e16794588 100644 --- a/source/blender/editors/armature/pose_transform.c +++ b/source/blender/editors/armature/pose_transform.c @@ -71,9 +71,12 @@ /* Pose Apply */ /* helper for apply_armature_pose2bones - fixes parenting of objects that are bone-parented to armature */ -static void applyarmature_fix_boneparents(Scene *scene, Object *armob) +static void applyarmature_fix_boneparents(const bContext *C, Scene *scene, Object *armob) { Object workob, *ob; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); /* go through all objects in database */ for (ob = G.main->object.first; ob; ob = ob->id.next) { @@ -84,7 +87,7 @@ static void applyarmature_fix_boneparents(Scene *scene, Object *armob) */ BKE_object_apply_mat4(ob, ob->obmat, false, false); - BKE_object_workob_calc_parent(scene, ob, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); } } @@ -95,10 +98,13 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); // must be active object, not edit-object + EvaluationContext eval_ctx; bArmature *arm = BKE_armature_from_object(ob); bPose *pose; bPoseChannel *pchan; EditBone *curbone; + + CTX_data_eval_ctx(C, &eval_ctx); /* don't check if editmode (should be done by caller) */ if (ob->type != OB_ARMATURE) @@ -168,10 +174,10 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) ED_armature_edit_free(arm); /* flush positions of posebones */ - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(&eval_ctx, scene, ob); /* fix parenting of objects which are bone-parented */ - applyarmature_fix_boneparents(scene, ob); + applyarmature_fix_boneparents(C, scene, ob); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); @@ -758,7 +764,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op, /* now recalculate paths */ if ((ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) - ED_pose_recalculate_paths(scene, ob); + ED_pose_recalculate_paths(C, scene, ob); } DEG_id_tag_update(&ob->id, OB_RECALC_DATA); diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c index 124cf24f12b..b17cc286333 100644 --- a/source/blender/editors/armature/pose_utils.c +++ b/source/blender/editors/armature/pose_utils.c @@ -182,6 +182,9 @@ void poseAnim_mapping_free(ListBase *pfLinks) void poseAnim_mapping_refresh(bContext *C, Scene *scene, Object *ob) { bArmature *arm = (bArmature *)ob->data; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); /* old optimize trick... this enforces to bypass the depgraph * - note: code copied from transform_generics.c -> recalcData() @@ -190,7 +193,7 @@ void poseAnim_mapping_refresh(bContext *C, Scene *scene, Object *ob) if ((arm->flag & ARM_DELAYDEFORM) == 0) DEG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ else - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(&eval_ctx, scene, ob); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); @@ -263,7 +266,7 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, Object *ob, ListBa */ if (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) { //ED_pose_clear_paths(C, ob); // XXX for now, don't need to clear - ED_pose_recalculate_paths(scene, ob); + ED_pose_recalculate_paths(C, scene, ob); } } } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 10d1fe303e9..abbe7197d92 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -5021,7 +5021,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) vc.ar, vc.v3d); ED_transform_snap_object_project_view3d_mixed( - snap_context, + C, snap_context, SCE_SELECT_FACE, &(const struct SnapObjectParams){ .snap_select = (vc.scene->obedit != NULL) ? SNAP_NOT_ACTIVE : SNAP_ALL, @@ -6275,12 +6275,15 @@ static int match_texture_space_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); Object *object = CTX_data_active_object(C); + EvaluationContext eval_ctx; Curve *curve = (Curve *) object->data; float min[3], max[3], size[3], loc[3]; int a; + CTX_data_eval_ctx(C, &eval_ctx); + if (object->curve_cache == NULL) { - BKE_displist_make_curveTypes(scene, object, false); + BKE_displist_make_curveTypes(&eval_ctx, scene, object, false); } INIT_MINMAX(min, max); diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 6d29d2def97..25bad71af88 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -75,94 +75,6 @@ /* Distance between start/end points to consider cyclic */ #define STROKE_CYCLIC_DIST_PX 8 - -/* -------------------------------------------------------------------- */ - -/** \name Depth Utilities - * \{ */ - - -static float depth_read_zbuf(const ViewContext *vc, int x, int y) -{ - ViewDepths *vd = vc->rv3d->depths; - - if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h) - return vd->depths[y * vd->w + x]; - else - return -1.0f; -} - -static bool depth_unproject( - const ARegion *ar, - const int mval[2], const double depth, - float r_location_world[3]) -{ - float centx = (float)mval[0] + 0.5f; - float centy = (float)mval[1] + 0.5f; - return ED_view3d_unproject(ar, centx, centy, depth, r_location_world); -} - -static bool depth_read_normal( - const ViewContext *vc, const int mval[2], - float r_normal[3]) -{ - /* pixels surrounding */ - bool depths_valid[9] = {false}; - float coords[9][3] = {{0}}; - - ARegion *ar = vc->ar; - const ViewDepths *depths = vc->rv3d->depths; - - for (int x = 0, i = 0; x < 2; x++) { - for (int y = 0; y < 2; y++) { - const int mval_ofs[2] = {mval[0] + (x - 1), mval[1] + (y - 1)}; - - const double depth = (double)depth_read_zbuf(vc, mval_ofs[0], mval_ofs[1]); - if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) { - if (depth_unproject(ar, mval_ofs, depth, coords[i])) { - depths_valid[i] = true; - } - } - i++; - } - } - - const int edges[2][6][2] = { - /* x edges */ - {{0, 1}, {1, 2}, - {3, 4}, {4, 5}, - {6, 7}, {7, 8}}, - /* y edges */ - {{0, 3}, {3, 6}, - {1, 4}, {4, 7}, - {2, 5}, {5, 8}}, - }; - - float cross[2][3] = {{0.0f}}; - - for (int i = 0; i < 6; i++) { - for (int axis = 0; axis < 2; axis++) { - if (depths_valid[edges[axis][i][0]] && depths_valid[edges[axis][i][1]]) { - float delta[3]; - sub_v3_v3v3(delta, coords[edges[axis][i][0]], coords[edges[axis][i][1]]); - add_v3_v3(cross[axis], delta); - } - } - } - - cross_v3_v3v3(r_normal, cross[0], cross[1]); - - if (normalize_v3(r_normal) != 0.0f) { - return true; - } - else { - return false; - } -} - -/** \} */ - - /* -------------------------------------------------------------------- */ /** \name StrokeElem / #RNA_OperatorStrokeElement Conversion Functions @@ -304,9 +216,9 @@ static bool stroke_elem_project( ((unsigned int)mval_i[0] < depths->w) && ((unsigned int)mval_i[1] < depths->h)) { - const double depth = (double)depth_read_zbuf(&cdd->vc, mval_i[0], mval_i[1]); + const double depth = (double)ED_view3d_depth_read_cached(&cdd->vc, mval_i); if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) { - if (depth_unproject(ar, mval_i, depth, r_location_world)) { + if (ED_view3d_depth_unproject(ar, mval_i, depth, r_location_world)) { is_location_world_set = true; if (r_normal_world) { zero_v3(r_normal_world); @@ -315,7 +227,7 @@ static bool stroke_elem_project( if (surface_offset != 0.0f) { const float offset = cdd->project.use_surface_offset_absolute ? 1.0f : radius; float normal[3]; - if (depth_read_normal(&cdd->vc, mval_i, normal)) { + if (ED_view3d_depth_read_cached_normal(&cdd->vc, mval_i, normal)) { madd_v3_v3fl(r_location_world, normal, offset * surface_offset); if (r_normal_world) { copy_v3_v3(r_normal_world, normal); @@ -642,7 +554,7 @@ static void curve_draw_event_add_first(wmOperator *op, const wmEvent *event) CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW, CURVE_PAINT_SURFACE_PLANE_NORMAL_SURFACE)) { - if (depth_read_normal(&cdd->vc, event->mval, normal)) { + if (ED_view3d_depth_read_cached_normal(&cdd->vc, event->mval, normal)) { if (cps->surface_plane == CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW) { float cross_a[3], cross_b[3]; cross_v3_v3v3(cross_a, rv3d->viewinv[2], normal); @@ -1182,7 +1094,7 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* needed or else the draw matrix can be incorrect */ view3d_operator_needs_opengl(C); - ED_view3d_autodist_init(cdd->vc.depsgraph, cdd->vc.ar, cdd->vc.v3d, 0); + ED_view3d_autodist_init(C, cdd->vc.depsgraph, cdd->vc.ar, cdd->vc.v3d, 0); if (cdd->vc.rv3d->depths) { cdd->vc.rv3d->depths->damaged = true; diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index c18f1408387..b09137c6a73 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -424,6 +424,7 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); SceneLayer *sl = CTX_data_scene_layer(C); + EvaluationContext eval_ctx; Curve *cu; Object *obedit; Base *base; @@ -433,13 +434,15 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const int a; float rot[3] = {0.f, 0.f, 0.f}; + CTX_data_eval_ctx(C, &eval_ctx); + obedit = BKE_object_add(bmain, scene, sl, OB_FONT, NULL); base = sl->basact; /* seems to assume view align ? TODO - look into this, could be an operator option */ ED_object_base_init_transform(C, base, NULL, rot); - BKE_object_where_is_calc(scene, obedit); + BKE_object_where_is_calc(&eval_ctx, scene, obedit); add_v3_v3(obedit->loc, offset); diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c index bd4856f1b93..9227f9b1097 100644 --- a/source/blender/editors/gpencil/editaction_gpencil.c +++ b/source/blender/editors/gpencil/editaction_gpencil.c @@ -314,7 +314,7 @@ void ED_gplayer_frames_keytype_set(bGPDlayer *gpl, short type) */ /* globals for copy/paste data (like for other copy/paste buffers) */ -ListBase gp_anim_copybuf = {NULL, NULL}; +static ListBase gp_anim_copybuf = {NULL, NULL}; static int gp_anim_copy_firstframe = 999999999; static int gp_anim_copy_lastframe = -999999999; static int gp_anim_copy_cfra = 0; diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c index f478596deec..ea21aa81d3d 100644 --- a/source/blender/editors/gpencil/gpencil_brush.c +++ b/source/blender/editors/gpencil/gpencil_brush.c @@ -710,7 +710,7 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in } else { /* ERROR */ - BLI_assert("3D stroke being sculpted in non-3D view"); + BLI_assert(!"3D stroke being sculpted in non-3D view"); } } else { diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 6310cab9e4e..ced7cd07347 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -343,7 +343,7 @@ ListBase gp_strokes_copypastebuf = {NULL, NULL}; * This is needed to prevent dangling and unsafe pointers when pasting across datablocks, * or after a color used by a stroke in the buffer gets deleted (via user action or undo). */ -GHash *gp_strokes_copypastebuf_colors = NULL; +static GHash *gp_strokes_copypastebuf_colors = NULL; /* Free copy/paste buffer data */ void ED_gpencil_strokes_copybuf_free(void) @@ -2108,7 +2108,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) if (mode == GP_REPROJECT_SURFACE) { struct Depsgraph *graph = CTX_data_depsgraph(C); view3d_region_operator_needs_opengl(CTX_wm_window(C), gsc.ar); - ED_view3d_autodist_init(graph, gsc.ar, CTX_wm_view3d(C), 0); + ED_view3d_autodist_init(C, graph, gsc.ar, CTX_wm_view3d(C), 0); } // TODO: For deforming geometry workflow, create new frames? diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 9b639ac42e4..834a1ced69d 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -484,7 +484,7 @@ static void gp_brush_angle(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const } /* add current stroke-point to buffer (returns whether point was successfully added) */ -static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure, double curtime) +static short gp_stroke_addpoint(const bContext *C, tGPsdata *p, const int mval[2], float pressure, double curtime) { bGPdata *gpd = p->gpd; bGPDbrush *brush = p->brush; @@ -643,7 +643,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure, view3d_region_operator_needs_opengl(p->win, p->ar); ED_view3d_autodist_init( - p->graph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); + C, p->graph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); } /* convert screen-coordinates to appropriate coordinates (and store them) */ @@ -679,7 +679,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure, * - applies a reverse Chaikin filter * - code adapted from etch-a-ton branch (editarmature_sketch.c) */ -static void gp_stroke_simplify(tGPsdata *p) +static void gp_stroke_simplify(const bContext *C, tGPsdata *p) { bGPdata *gpd = p->gpd; tGPspoint *old_points = (tGPspoint *)gpd->sbuffer; @@ -715,7 +715,7 @@ static void gp_stroke_simplify(tGPsdata *p) } (void)0 /* XXX Here too, do not lose start and end points! */ - gp_stroke_addpoint(p, &old_points->x, old_points->pressure, p->inittime + (double)old_points->time); + gp_stroke_addpoint(C, p, &old_points->x, old_points->pressure, p->inittime + (double)old_points->time); for (i = 0, j = 0; i < num_points; i++) { if (i - j == 3) { float co[2], pressure, time; @@ -738,12 +738,12 @@ static void gp_stroke_simplify(tGPsdata *p) mco[1] = (int)co[1]; /* ignore return values on this... assume to be ok for now */ - gp_stroke_addpoint(p, mco, pressure, p->inittime + (double)time); + gp_stroke_addpoint(C, p, mco, pressure, p->inittime + (double)time); j += 2; } } - gp_stroke_addpoint(p, &old_points[num_points - 1].x, old_points[num_points - 1].pressure, + gp_stroke_addpoint(C, p, &old_points[num_points - 1].x, old_points[num_points - 1].pressure, p->inittime + (double)old_points[num_points - 1].time); /* free old buffer */ @@ -1228,7 +1228,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, } /* erase strokes which fall under the eraser strokes */ -static void gp_stroke_doeraser(tGPsdata *p) +static void gp_stroke_doeraser(const bContext *C, tGPsdata *p) { bGPDlayer *gpl; bGPDstroke *gps, *gpn; @@ -1244,7 +1244,7 @@ static void gp_stroke_doeraser(tGPsdata *p) if (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH) { View3D *v3d = p->sa->spacedata.first; view3d_region_operator_needs_opengl(p->win, p->ar); - ED_view3d_autodist_init(p->graph, p->ar, v3d, 0); + ED_view3d_autodist_init(C, p->graph, p->ar, v3d, 0); } } @@ -1800,7 +1800,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode) } /* finish off a stroke (clears buffer, but doesn't finish the paint operation) */ -static void gp_paint_strokeend(tGPsdata *p) +static void gp_paint_strokeend(const bContext *C, tGPsdata *p) { ToolSettings *ts = p->scene->toolsettings; /* for surface sketching, need to set the right OpenGL context stuff so that @@ -1811,13 +1811,13 @@ static void gp_paint_strokeend(tGPsdata *p) /* need to restore the original projection settings before packing up */ view3d_region_operator_needs_opengl(p->win, p->ar); - ED_view3d_autodist_init(p->graph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); + ED_view3d_autodist_init(C, p->graph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); } /* check if doing eraser or not */ if ((p->gpd->sbuffer_sflag & GP_STROKE_ERASER) == 0) { /* simplify stroke before transferring? */ - gp_stroke_simplify(p); + gp_stroke_simplify(C, p); /* transfer stroke to frame */ gp_stroke_newfrombuffer(p); @@ -1828,14 +1828,14 @@ static void gp_paint_strokeend(tGPsdata *p) } /* finish off stroke painting operation */ -static void gp_paint_cleanup(tGPsdata *p) +static void gp_paint_cleanup(const bContext *C, tGPsdata *p) { /* p->gpd==NULL happens when stroke failed to initialize, * for example when GP is hidden in current space (sergey) */ if (p->gpd) { /* finish off a stroke */ - gp_paint_strokeend(p); + gp_paint_strokeend(C, p); } /* "unlock" frame */ @@ -1941,7 +1941,7 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op) U.gp_eraser = p->radius; /* cleanup */ - gp_paint_cleanup(p); + gp_paint_cleanup(C, p); gp_session_cleanup(p); /* finally, free the temp data */ @@ -2051,12 +2051,12 @@ static void gpencil_draw_status_indicators(tGPsdata *p) /* ------------------------------- */ /* create a new stroke point at the point indicated by the painting context */ -static void gpencil_draw_apply(wmOperator *op, tGPsdata *p) +static void gpencil_draw_apply(const bContext *C, wmOperator *op, tGPsdata *p) { /* handle drawing/erasing -> test for erasing first */ if (p->paintmode == GP_PAINTMODE_ERASER) { /* do 'live' erasing now */ - gp_stroke_doeraser(p); + gp_stroke_doeraser(C, p); /* store used values */ p->mvalo[0] = p->mval[0]; @@ -2066,12 +2066,12 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p) /* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */ else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) { /* try to add point */ - short ok = gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime); + short ok = gp_stroke_addpoint(C, p, p->mval, p->pressure, p->curtime); /* handle errors while adding point */ if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) { /* finish off old stroke */ - gp_paint_strokeend(p); + gp_paint_strokeend(C, p); /* And start a new one!!! Else, projection errors! */ gp_paint_initstroke(p, p->paintmode); @@ -2080,12 +2080,12 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p) /* XXX We only need to reuse previous point if overflow! */ if (ok == GP_STROKEADD_OVERFLOW) { p->inittime = p->ocurtime; - gp_stroke_addpoint(p, p->mvalo, p->opressure, p->ocurtime); + gp_stroke_addpoint(C, p, p->mvalo, p->opressure, p->ocurtime); } else { p->inittime = p->curtime; } - gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime); + gp_stroke_addpoint(C, p, p->mval, p->pressure, p->curtime); } else if (ok == GP_STROKEADD_INVALID) { /* the painting operation cannot continue... */ @@ -2106,7 +2106,7 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p) } /* handle draw event */ -static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event) +static void gpencil_draw_apply_event(const bContext *C, wmOperator *op, const wmEvent *event) { tGPsdata *p = op->customdata; PointerRNA itemptr; @@ -2211,7 +2211,7 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event) RNA_float_set(&itemptr, "time", p->curtime - p->inittime); /* apply the current latest drawing point */ - gpencil_draw_apply(op, p); + gpencil_draw_apply(C, op, p); /* force refresh */ ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */ @@ -2259,7 +2259,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op) */ if ((p->flags & GP_PAINTFLAG_FIRSTRUN) == 0) { /* TODO: both of these ops can set error-status, but we probably don't need to worry */ - gp_paint_strokeend(p); + gp_paint_strokeend(C, p); gp_paint_initstroke(p, p->paintmode); } } @@ -2275,7 +2275,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op) } /* apply this data as necessary now (as per usual) */ - gpencil_draw_apply(op, p); + gpencil_draw_apply(C, op, p); } RNA_END; @@ -2334,7 +2334,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event p->status = GP_STATUS_PAINTING; /* handle the initial drawing - i.e. for just doing a simple dot */ - gpencil_draw_apply_event(op, event); + gpencil_draw_apply_event(C, op, event); op->flag |= OP_IS_MODAL_CURSOR_REGION; } else { @@ -2385,11 +2385,11 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op) return op->customdata; } -static void gpencil_stroke_end(wmOperator *op) +static void gpencil_stroke_end(bContext *C, wmOperator *op) { tGPsdata *p = op->customdata; - gp_paint_cleanup(p); + gp_paint_cleanup(C, p); gpencil_undo_push(p->gpd); @@ -2523,7 +2523,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) if (sketch) { /* end stroke only, and then wait to resume painting soon */ /* printf("\t\tGP - end stroke only\n"); */ - gpencil_stroke_end(op); + gpencil_stroke_end(C, op); /* If eraser mode is on, turn it off after the stroke finishes * NOTE: This just makes it nicer to work with drawing sessions @@ -2666,7 +2666,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) || (p->flags & GP_PAINTFLAG_FIRSTRUN)) { /* handle drawing event */ /* printf("\t\tGP - add point\n"); */ - gpencil_draw_apply_event(op, event); + gpencil_draw_apply_event(C, op, event); /* finish painting operation if anything went wrong just now */ if (p->status == GP_STATUS_ERROR) { diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 82892561daa..07fac0fdfac 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -542,7 +542,7 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc) view3d_operator_needs_opengl(C); view3d_region_operator_needs_opengl(win, ar); - ED_view3d_autodist_init(graph, ar, v3d, 0); + ED_view3d_autodist_init(C, graph, ar, v3d, 0); /* for camera view set the subrect */ if (rv3d->persp == RV3D_CAMOB) { diff --git a/source/blender/editors/hair/hair_edit.c b/source/blender/editors/hair/hair_edit.c index 269ca5833fa..ccf66e34f90 100644 --- a/source/blender/editors/hair/hair_edit.c +++ b/source/blender/editors/hair/hair_edit.c @@ -162,6 +162,8 @@ static int hair_edit_toggle_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); const int mode_flag = OB_MODE_HAIR_EDIT; const bool is_mode_set = (ob->mode & mode_flag) != 0; + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); if (!is_mode_set) { if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { @@ -171,9 +173,9 @@ static int hair_edit_toggle_exec(bContext *C, wmOperator *op) if (!is_mode_set) { #if USE_PARTICLES - ED_hair_object_init_particle_edit(scene, ob); + ED_hair_object_init_particle_edit(&eval_ctx, scene, ob); #else - ED_hair_object_init_mesh_edit(scene, ob); + ED_hair_object_init_mesh_edit(&eval_ctx, scene, ob); #endif ob->mode |= mode_flag; @@ -230,7 +232,7 @@ void hair_init_viewcontext(bContext *C, ViewContext *vc) /* needed or else the draw matrix can be incorrect */ view3d_operator_needs_opengl(C); - ED_view3d_backbuf_validate(vc); + ED_view3d_backbuf_validate(C, vc); /* we may need to force an update here by setting the rv3d as dirty * for now it seems ok, but take care!: * rv3d->depths->dirty = 1; */ diff --git a/source/blender/editors/hair/hair_intern.h b/source/blender/editors/hair/hair_intern.h index 178671c1c60..2a8590d5679 100644 --- a/source/blender/editors/hair/hair_intern.h +++ b/source/blender/editors/hair/hair_intern.h @@ -40,6 +40,7 @@ struct ARegion; struct bContext; struct wmOperatorType; struct rcti; +struct EvaluationContext; struct Object; @@ -60,12 +61,12 @@ void HAIR_OT_select_linked(struct wmOperatorType *ot); void HAIR_OT_stroke(struct wmOperatorType *ot); /* hair_object_mesh.c */ -bool ED_hair_object_init_mesh_edit(struct Scene *scene, struct Object *ob); +bool ED_hair_object_init_mesh_edit(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); bool ED_hair_object_apply_mesh_edit(struct Object *ob); /* hair_object_particles.c */ bool ED_hair_object_has_hair_particle_data(struct Object *ob); -bool ED_hair_object_init_particle_edit(struct Scene *scene, struct Object *ob); +bool ED_hair_object_init_particle_edit(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); bool ED_hair_object_apply_particle_edit(struct Object *ob); diff --git a/source/blender/editors/hair/hair_object_mesh.c b/source/blender/editors/hair/hair_object_mesh.c index a1140c0be13..887eed12042 100644 --- a/source/blender/editors/hair/hair_object_mesh.c +++ b/source/blender/editors/hair/hair_object_mesh.c @@ -47,7 +47,7 @@ #include "hair_intern.h" -bool ED_hair_object_init_mesh_edit(Scene *UNUSED(scene), Object *ob) +bool ED_hair_object_init_mesh_edit(struct EvaluationContext *UNUSED(eval_ctx), Scene *UNUSED(scene), Object *ob) { if (ob->type == OB_MESH) { Mesh *me = ob->data; diff --git a/source/blender/editors/hair/hair_object_particles.c b/source/blender/editors/hair/hair_object_particles.c index bee56f2aeb9..f39ccdec6e2 100644 --- a/source/blender/editors/hair/hair_object_particles.c +++ b/source/blender/editors/hair/hair_object_particles.c @@ -58,7 +58,7 @@ bool ED_hair_object_has_hair_particle_data(Object *ob) return false; } -bool ED_hair_object_init_particle_edit(Scene *scene, Object *ob) +bool ED_hair_object_init_particle_edit(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob) { ParticleSystem *psys = psys_get_current(ob); BMesh *bm; @@ -69,7 +69,7 @@ bool ED_hair_object_init_particle_edit(Scene *scene, Object *ob) bm = BKE_editstrands_particles_to_bmesh(ob, psys); if (ob->type == OB_MESH || ob->derivedFinal) - dm = ob->derivedFinal ? ob->derivedFinal : mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + dm = ob->derivedFinal ? ob->derivedFinal : mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH); else dm = NULL; diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index a65c6eec6ae..f9c90713f40 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -257,7 +257,7 @@ typedef enum eAnimFilter_Flags { ANIMFILTER_TMP_PEEK = (1 << 30), /* ignore ONLYSEL flag from filterflag, (internal use only!) */ - ANIMFILTER_TMP_IGNORE_ONLYSEL = (1 << 31) + ANIMFILTER_TMP_IGNORE_ONLYSEL = (1u << 31) } eAnimFilter_Flags; /* ---------- Flag Checking Macros ------------ */ diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 7866bed8666..7066095a93a 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -174,8 +174,8 @@ void ED_armature_transform(struct bArmature *arm, float mat[4][4]); #define ARM_GROUPS_ENVELOPE 2 #define ARM_GROUPS_AUTO 3 -void create_vgroups_from_armature(struct ReportList *reports, struct Scene *scene, struct Object *ob, - struct Object *par, const int mode, const bool mirror); +void create_vgroups_from_armature(struct ReportList *reports, const struct bContext *C, struct Scene *scene, + struct Object *ob, struct Object *par, const int mode, const bool mirror); /* if bone is already in list, pass it as param to ignore it */ void unique_editbone_name(struct ListBase *ebones, char *name, EditBone *bone); @@ -196,7 +196,7 @@ void ED_armature_exit_posemode(struct bContext *C, struct Base *base); void ED_armature_enter_posemode(struct bContext *C, struct Base *base); void ED_pose_de_selectall(struct Object *ob, int select_mode, const bool ignore_visibility); void ED_pose_bone_select(struct Object *ob, struct bPoseChannel *pchan, bool select); -void ED_pose_recalculate_paths(struct Scene *scene, struct Object *ob); +void ED_pose_recalculate_paths(struct bContext *C, struct Scene *scene, struct Object *ob); struct Object *ED_pose_object_from_context(struct bContext *C); /* sketch */ diff --git a/source/blender/editors/include/ED_manipulator_library.h b/source/blender/editors/include/ED_manipulator_library.h index b1970a7bab3..b8981acf1da 100644 --- a/source/blender/editors/include/ED_manipulator_library.h +++ b/source/blender/editors/include/ED_manipulator_library.h @@ -57,7 +57,8 @@ void ED_manipulator_draw_preset_arrow( void ED_manipulator_draw_preset_circle( const struct wmManipulator *mpr, float mat[4][4], int axis, int select_id); void ED_manipulator_draw_preset_facemap( - const struct wmManipulator *mpr, struct Scene *scene, struct Object *ob, const int facemap, int select_id); + const struct bContext *C, const struct wmManipulator *mpr, struct Scene *scene, + struct Object *ob, const int facemap, int select_id); /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 0ee60471357..c3186f7afdf 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -134,35 +134,35 @@ void EDBM_select_mirrored( int *r_totmirr, int *r_totfail); void EDBM_automerge(struct Scene *scene, struct Object *ob, bool update, const char hflag); -bool EDBM_backbuf_border_init(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); +bool EDBM_backbuf_border_init(const struct bContext *C, struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); bool EDBM_backbuf_check(unsigned int index); void EDBM_backbuf_free(void); -bool EDBM_backbuf_border_mask_init(struct ViewContext *vc, const int mcords[][2], short tot, +bool EDBM_backbuf_border_mask_init(const struct bContext *C, struct ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax); -bool EDBM_backbuf_circle_init(struct ViewContext *vc, short xs, short ys, short rads); +bool EDBM_backbuf_circle_init(const struct bContext *C, struct ViewContext *vc, short xs, short ys, short rads); struct BMVert *EDBM_vert_find_nearest_ex( - struct ViewContext *vc, float *r_dist, + const struct bContext *C, struct ViewContext *vc, float *r_dist, const bool use_select_bias, bool use_cycle); struct BMVert *EDBM_vert_find_nearest( - struct ViewContext *vc, float *r_dist); + const struct bContext *C, struct ViewContext *vc, float *r_dist); struct BMEdge *EDBM_edge_find_nearest_ex( - struct ViewContext *vc, float *r_dist, + const struct bContext *C, struct ViewContext *vc, float *r_dist, float *r_dist_center, const bool use_select_bias, const bool use_cycle, struct BMEdge **r_eed_zbuf); struct BMEdge *EDBM_edge_find_nearest( - struct ViewContext *vc, float *r_dist); + const struct bContext *C, struct ViewContext *vc, float *r_dist); struct BMFace *EDBM_face_find_nearest_ex( - struct ViewContext *vc, float *r_dist, + const struct bContext *C, struct ViewContext *vc, float *r_dist, float *r_dist_center, const bool use_select_bias, const bool use_cycle, struct BMFace **r_efa_zbuf); struct BMFace *EDBM_face_find_nearest( - struct ViewContext *vc, float *r_dist); + const struct bContext *C, struct ViewContext *vc, float *r_dist); bool EDBM_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle); @@ -199,7 +199,7 @@ void EMBM_project_snap_verts(struct bContext *C, struct ARegion *ar, struct BMEd /* editface.c */ void paintface_flush_flags(struct Object *ob, short flag); bool paintface_mouse_select(struct bContext *C, struct Object *ob, const int mval[2], bool extend, bool deselect, bool toggle); -int do_paintface_box_select(struct ViewContext *vc, struct rcti *rect, bool select, bool extend); +int do_paintface_box_select(const struct bContext *C, struct ViewContext *vc, struct rcti *rect, bool select, bool extend); void paintface_deselect_all_visible(struct Object *ob, int action, bool flush_flags); void paintface_select_linked(struct bContext *C, struct Object *ob, const int mval[2], const bool select); bool paintface_minmax(struct Object *ob, float r_min[3], float r_max[3]); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 9e5d55dd031..56a91d9846c 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -88,7 +88,7 @@ extern struct EnumPropertyItem prop_clear_parent_types[]; extern struct EnumPropertyItem prop_make_parent_types[]; #endif -bool ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, +bool ED_object_parent_set(struct ReportList *reports, const struct bContext *C, struct Scene *scene, struct Object *ob, struct Object *par, int partype, const bool xmirror, const bool keep_transform, const int vert_par[3]); void ED_object_parent_clear(struct Object *ob, const int type); @@ -200,7 +200,7 @@ int ED_object_modifier_move_down(struct ReportList *reports, struct Object *ob, int ED_object_modifier_move_up(struct ReportList *reports, struct Object *ob, struct ModifierData *md); int ED_object_modifier_convert(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct SceneLayer *sl, struct Object *ob, struct ModifierData *md); -int ED_object_modifier_apply(struct ReportList *reports, struct Scene *scene, +int ED_object_modifier_apply(struct ReportList *reports, const struct bContext *C, struct Scene *scene, struct Object *ob, struct ModifierData *md, int mode); int ED_object_modifier_copy(struct ReportList *reports, struct Object *ob, struct ModifierData *md); diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h index 41c746aa421..7bce95182bf 100644 --- a/source/blender/editors/include/ED_particle.h +++ b/source/blender/editors/include/ED_particle.h @@ -46,14 +46,15 @@ int PE_start_edit(struct PTCacheEdit *edit); /* access */ struct PTCacheEdit *PE_get_current(struct Scene *scene, struct SceneLayer *sl, struct Object *ob); -struct PTCacheEdit *PE_create_current(struct Scene *scene, struct Object *ob); -void PE_current_changed(struct Scene *scene, struct Object *ob); +struct PTCacheEdit *PE_create_current(const struct bContext *C, struct Scene *scene, struct Object *ob); +void PE_current_changed(const struct bContext *C, struct Scene *scene, struct Object *ob); int PE_minmax(struct Scene *scene, struct SceneLayer *sl, float min[3], float max[3]); struct ParticleEditSettings *PE_settings(struct Scene *scene); /* update calls */ void PE_hide_keys_time(struct Scene *scene, struct PTCacheEdit *edit, float cfra); -void PE_update_object(struct Scene *scene, struct SceneLayer *sl, struct Object *ob, int useflag); +void PE_update_object(const struct bContext *C, struct Scene *scene, + struct SceneLayer *sl, struct Object *ob, int useflag); /* selection tools */ int PE_mouse_particles(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle); diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 483caf7c475..39dd6024022 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -182,7 +182,7 @@ bool peelObjectsTransform( /* return args */ float r_loc[3], float r_no[3], float *r_thickness); bool peelObjectsSnapContext( - struct SnapObjectContext *sctx, + const struct bContext *C, struct SnapObjectContext *sctx, const float mval[2], const struct SnapObjectParams *params, const bool use_peel_object, diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h index 1bc22e79625..4f93c35b8d6 100644 --- a/source/blender/editors/include/ED_transform_snap_object_context.h +++ b/source/blender/editors/include/ED_transform_snap_object_context.h @@ -36,6 +36,7 @@ struct Main; struct Object; struct ARegion; struct View3D; +struct bContext; /* transform_snap_object.c */ @@ -84,34 +85,34 @@ void ED_transform_snap_object_context_set_editmesh_callbacks( void *user_data); bool ED_transform_snap_object_project_ray_ex( - struct SnapObjectContext *sctx, + const struct bContext *C, struct SnapObjectContext *sctx, const struct SnapObjectParams *params, const float ray_start[3], const float ray_normal[3], float *ray_depth, /* return args */ float r_loc[3], float r_no[3], int *r_index, struct Object **r_ob, float r_obmat[4][4]); bool ED_transform_snap_object_project_ray( - SnapObjectContext *sctx, + const struct bContext *C, SnapObjectContext *sctx, const struct SnapObjectParams *params, const float ray_origin[3], const float ray_direction[3], float *ray_depth, float r_co[3], float r_no[3]); bool ED_transform_snap_object_project_ray_all( - SnapObjectContext *sctx, + const struct bContext *C, SnapObjectContext *sctx, const struct SnapObjectParams *params, const float ray_start[3], const float ray_normal[3], float ray_depth, bool sort, struct ListBase *r_hit_list); bool ED_transform_snap_object_project_view3d_ex( - struct SnapObjectContext *sctx, + const struct bContext *C, struct SnapObjectContext *sctx, const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], float *dist_px, float *ray_depth, float r_loc[3], float r_no[3], int *r_index); bool ED_transform_snap_object_project_view3d( - struct SnapObjectContext *sctx, + const struct bContext *C, struct SnapObjectContext *sctx, const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], float *dist_px, @@ -119,7 +120,7 @@ bool ED_transform_snap_object_project_view3d( /* return args */ float r_loc[3], float r_no[3]); bool ED_transform_snap_object_project_view3d_mixed( - SnapObjectContext *sctx, + const struct bContext *C, SnapObjectContext *sctx, const unsigned short snap_to_flag, const struct SnapObjectParams *params, const float mval_fl[2], float *dist_px, @@ -127,7 +128,7 @@ bool ED_transform_snap_object_project_view3d_mixed( float r_co[3], float r_no[3]); bool ED_transform_snap_object_project_all_view3d_ex( - SnapObjectContext *sctx, + const struct bContext *C, SnapObjectContext *sctx, const struct SnapObjectParams *params, const float mval[2], float ray_depth, bool sort, diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 19bb55742d5..4b7eaa4f3d4 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -42,6 +42,7 @@ struct BezTriple; struct BoundBox; struct Depsgraph; struct EditBone; +struct EvaluationContext; struct ImBuf; struct MVert; struct Main; @@ -109,7 +110,14 @@ void ED_view3d_lastview_store(struct RegionView3D *rv3d); /* Depth buffer */ void ED_view3d_depth_update(struct ARegion *ar); -float ED_view3d_depth_read_cached(const struct ViewContext *vc, int x, int y); +float ED_view3d_depth_read_cached(const struct ViewContext *vc, const int mval[2]); +bool ED_view3d_depth_read_cached_normal( + const ViewContext *vc, const int mval[2], + float r_normal[3]); +bool ED_view3d_depth_unproject( + const struct ARegion *ar, + const int mval[2], const double depth, + float r_location_world[3]); void ED_view3d_depth_tag_update(struct RegionView3D *rv3d); /* Projection */ @@ -144,20 +152,20 @@ typedef enum { /* foreach iterators */ void meshobject_foreachScreenVert( - struct ViewContext *vc, + const struct bContext *C, struct ViewContext *vc, void (*func)(void *userData, struct MVert *eve, const float screen_co[2], int index), void *userData, const eV3DProjTest clip_flag); void mesh_foreachScreenVert( - struct ViewContext *vc, + const struct bContext *C, struct ViewContext *vc, void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index), void *userData, const eV3DProjTest clip_flag); void mesh_foreachScreenEdge( - struct ViewContext *vc, + const struct bContext *C, struct ViewContext *vc, void (*func)(void *userData, struct BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), void *userData, const eV3DProjTest clip_flag); void mesh_foreachScreenFace( - struct ViewContext *vc, + const struct bContext *C, struct ViewContext *vc, void (*func)(void *userData, struct BMFace *efa, const float screen_co[2], int index), void *userData, const eV3DProjTest clip_flag); void nurbs_foreachScreenVert( @@ -287,21 +295,21 @@ float ED_view3d_radius_to_dist( void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos); /* backbuffer select and draw support */ -void ED_view3d_backbuf_validate(struct ViewContext *vc); -struct ImBuf *ED_view3d_backbuf_read(struct ViewContext *vc, int xmin, int ymin, int xmax, int ymax); +void ED_view3d_backbuf_validate(const struct bContext *C, struct ViewContext *vc); +struct ImBuf *ED_view3d_backbuf_read(const struct bContext *C, struct ViewContext *vc, int xmin, int ymin, int xmax, int ymax); unsigned int ED_view3d_backbuf_sample_rect( - struct ViewContext *vc, const int mval[2], int size, + const struct bContext *C, struct ViewContext *vc, const int mval[2], int size, unsigned int min, unsigned int max, float *r_dist); int ED_view3d_backbuf_sample_size_clamp(struct ARegion *ar, const float dist); -unsigned int ED_view3d_backbuf_sample(struct ViewContext *vc, int x, int y); +unsigned int ED_view3d_backbuf_sample(const struct bContext *C, struct ViewContext *vc, int x, int y); bool ED_view3d_autodist( - struct Depsgraph *graph, struct ARegion *ar, struct View3D *v3d, + const struct bContext *C, struct Depsgraph *graph, struct ARegion *ar, struct View3D *v3d, const int mval[2], float mouse_worldloc[3], const bool alphaoverride, const float fallback_depth_pt[3]); /* only draw so ED_view3d_autodist_simple can be called many times after */ -void ED_view3d_autodist_init(struct Depsgraph *graph, struct ARegion *ar, struct View3D *v3d, int mode); +void ED_view3d_autodist_init(const struct bContext *C, struct Depsgraph *graph, struct ARegion *ar, struct View3D *v3d, int mode); bool ED_view3d_autodist_simple(struct ARegion *ar, const int mval[2], float mouse_worldloc[3], int margin, float *force_depth); bool ED_view3d_autodist_depth(struct ARegion *ar, const int mval[2], int margin, float *depth); bool ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], const int mval_end[2], int margin, float *depth); @@ -323,7 +331,7 @@ void view3d_opengl_select_cache_begin(void); void view3d_opengl_select_cache_end(void); int view3d_opengl_select( - struct ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const struct rcti *input, + const struct bContext *C, struct ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const struct rcti *input, eV3DSelectMode select_mode); /* view3d_select.c */ @@ -355,26 +363,26 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active); struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d); void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat); -void ED_draw_object_facemap(struct Scene *scene, struct Object *ob, const float col[4], const int facemap); +void ED_draw_object_facemap(const struct bContext *C, struct Scene *scene, struct Object *ob, const float col[4], const int facemap); bool ED_view3d_context_activate(struct bContext *C); -void ED_view3d_draw_offscreen_init(struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d); +void ED_view3d_draw_offscreen_init(struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d); void ED_view3d_draw_offscreen( - struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4], + struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4], float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, const char *viewname, struct GPUFX *fx, struct GPUFXSettings *fx_settings, struct GPUOffScreen *ofs); void ED_view3d_draw_setup_view( - struct wmWindow *win, struct Scene *scene, struct ARegion *ar, struct View3D *v3d, + struct wmWindow *win, const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct View3D *v3d, float viewmat[4][4], float winmat[4][4], const struct rcti *rect); struct ImBuf *ED_view3d_draw_offscreen_imbuf( - struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, - unsigned int flag, bool draw_background, + struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct ARegion *ar, + int sizex, int sizey, unsigned int flag, bool draw_background, int alpha_mode, int samples, bool full_samples, const char *viewname, struct GPUFX *fx, struct GPUOffScreen *ofs, char err_out[256]); struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple( - struct Scene *scene, struct SceneLayer *sl, struct Object *camera, int width, int height, + struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct Object *camera, int width, int height, unsigned int flag, int drawtype, bool use_solid_tex, bool use_gpencil, bool draw_background, int alpha_mode, int samples, bool full_samples, const char *viewname, struct GPUFX *fx, struct GPUOffScreen *ofs, char err_out[256]); @@ -382,7 +390,7 @@ struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple( struct BaseLegacy *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]); void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_clip); void ED_view3d_update_viewmat( - struct Scene *scene, struct View3D *v3d, struct ARegion *ar, + struct EvaluationContext *eval_ctx, struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4], const struct rcti *rect); bool ED_view3d_quat_from_axis_view(const char view, float quat[4]); char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 42386c7ecac..ed989f73523 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -212,6 +212,8 @@ enum { UI_BUT_ALIGN_STITCH_TOP = (1 << 18), UI_BUT_ALIGN_STITCH_LEFT = (1 << 19), UI_BUT_ALIGN_ALL = (UI_BUT_ALIGN | UI_BUT_ALIGN_STITCH_TOP | UI_BUT_ALIGN_STITCH_LEFT), + + UI_BUT_BOX_ITEM = (1 << 20), /* This but is "inside" a box item (currently used to change theme colors). */ }; /* scale fixed button widths by this to account for DPI */ @@ -1101,7 +1103,7 @@ void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p); /* Float precision helpers */ -#define UI_PRECISION_FLOAT_MAX 7 +#define UI_PRECISION_FLOAT_MAX 6 /* For float buttons the 'step' (or a1), is scaled */ #define UI_PRECISION_FLOAT_SCALE 0.01f diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index d8812b85c19..bea59649440 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -685,7 +685,7 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu if (oldbut->active) { /* flags from the buttons we want to refresh, may want to add more here... */ - const int flag_copy = UI_BUT_REDALERT; + const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON; found_active = true; @@ -1166,6 +1166,8 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) uiBut *but; char buf[128]; + BLI_assert(block->flag & UI_BLOCK_LOOP); + /* only do it before bounding */ if (block->rect.xmin != block->rect.xmax) return; @@ -1180,6 +1182,9 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) } else { for (but = block->buttons.first; but; but = but->next) { + if (but->dt != UI_EMBOSS_PULLDOWN) { + continue; + } if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) { ui_but_add_shortcut(but, buf, false); @@ -2144,9 +2149,14 @@ static float ui_get_but_step_unit(uiBut *but, float step_default) /** * \param float_precision For number buttons the precision to use or -1 to fallback to the button default. + * \param use_exp_float Use exponent representation of floats when out of reasonable range (outside of 1e3/1e-3). */ -void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) +void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision, const bool use_exp_float, bool *r_use_exp_float) { + if (r_use_exp_float) { + *r_use_exp_float = false; + } + if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) { PropertyType type; const char *buf = NULL; @@ -2214,17 +2224,38 @@ void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int ui_get_but_string_unit(but, str, maxlen, value, false, float_precision); } else { - const int prec = (float_precision == -1) ? ui_but_calc_float_precision(but, value) : float_precision; - BLI_snprintf(str, maxlen, "%.*f", prec, value); + int prec = (float_precision == -1) ? ui_but_calc_float_precision(but, value) : float_precision; + if (use_exp_float) { + const int int_digits_num = integer_digits_f(value); + if (int_digits_num < -6 || int_digits_num > 12) { + BLI_snprintf(str, maxlen, "%.*g", prec, value); + if (r_use_exp_float) { + *r_use_exp_float = true; + } + } + else { + prec -= int_digits_num; + CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX); + BLI_snprintf(str, maxlen, "%.*f", prec, value); + } + } + else { +#if 0 /* TODO, but will likely break some stuff, so better after 2.79 release. */ + prec -= int_digits_num; + CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX); +#endif + BLI_snprintf(str, maxlen, "%.*f", prec, value); + } } } - else + else { BLI_snprintf(str, maxlen, "%d", (int)value); + } } } void ui_but_string_get(uiBut *but, char *str, const size_t maxlen) { - ui_but_string_get_ex(but, str, maxlen, -1); + ui_but_string_get_ex(but, str, maxlen, -1, false, NULL); } /** diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c index a1ba937d925..40c6058c7c3 100644 --- a/source/blender/editors/interface/interface_eyedropper.c +++ b/source/blender/editors/interface/interface_eyedropper.c @@ -921,7 +921,7 @@ static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx, view3d_operator_needs_opengl(C); - if (ED_view3d_autodist(graph, ar, v3d, mval, co, true, NULL)) { + if (ED_view3d_autodist(C, graph, ar, v3d, mval, co, true, NULL)) { const float mval_center_fl[2] = { (float)ar->winx / 2, (float)ar->winy / 2}; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 59064ec332e..278cd511abb 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2313,7 +2313,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, /* Get many decimal places, then strip trailing zeros. * note: too high values start to give strange results */ char buf_copy[UI_MAX_DRAW_STR]; - ui_but_string_get_ex(but, buf_copy, sizeof(buf_copy), UI_PRECISION_FLOAT_MAX); + ui_but_string_get_ex(but, buf_copy, sizeof(buf_copy), UI_PRECISION_FLOAT_MAX, false, NULL); BLI_str_rstrip_float_zero(buf_copy, '\0'); WM_clipboard_text_set(buf_copy, 0); @@ -3054,6 +3054,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) wmWindow *win = CTX_wm_window(C); int len; const bool is_num_but = ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER); + bool no_zero_strip = false; if (data->str) { MEM_freeN(data->str); @@ -3082,14 +3083,16 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) data->maxlen = ui_but_string_get_max_length(but); if (data->maxlen != 0) { data->str = MEM_callocN(sizeof(char) * data->maxlen, "textedit str"); - ui_but_string_get(but, data->str, data->maxlen); + /* We do not want to truncate precision to default here, it's nice to show value, + * not to edit it - way too much precision is lost then. */ + ui_but_string_get_ex(but, data->str, data->maxlen, UI_PRECISION_FLOAT_MAX, true, &no_zero_strip); } else { data->is_str_dynamic = true; data->str = ui_but_string_get_dynamic(but, &data->maxlen); } - if (ui_but_is_float(but) && !ui_but_is_unit(but) && !ui_but_anim_expression_get(but, NULL, 0)) { + if (ui_but_is_float(but) && !ui_but_is_unit(but) && !ui_but_anim_expression_get(but, NULL, 0) && !no_zero_strip) { BLI_str_rstrip_float_zero(data->str, '\0'); } diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index ace3bb5b4f8..2abb8dcf20f 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -475,7 +475,9 @@ extern void ui_hsvcircle_pos_from_vals(struct uiBut *but, const rcti *rect, floa extern void ui_hsvcube_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xp, float *yp); bool ui_but_is_colorpicker_display_space(struct uiBut *but); -extern void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) ATTR_NONNULL(); +extern void ui_but_string_get_ex( + uiBut *but, char *str, const size_t maxlen, + const int float_precision, const bool use_exp_float, bool *r_use_exp_float) ATTR_NONNULL(1, 2); extern void ui_but_string_get(uiBut *but, char *str, const size_t maxlen) ATTR_NONNULL(); extern char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size); extern void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) ATTR_NONNULL(); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 0b7f4b00c2d..3c26798f886 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -128,6 +128,8 @@ typedef struct uiItem { enum { UI_ITEM_FIXED = 1 << 0, UI_ITEM_MIN = 1 << 1, + + UI_ITEM_BOX_ITEM = 1 << 2, /* The item is "inside" a box item */ }; typedef struct uiButtonItem { @@ -192,8 +194,9 @@ static const char *ui_item_name_add_colon(const char *name, char namestr[UI_MAX_ static int ui_item_fit(int item, int pos, int all, int available, bool is_last, int alignment, float *extra_pixel) { /* available == 0 is unlimited */ - if (available == 0) + if (ELEM(0, available, all)) { return item; + } if (all > available) { /* contents is bigger than available space */ @@ -216,8 +219,9 @@ static int ui_item_fit(int item, int pos, int all, int available, bool is_last, return (int)width; } } - else + else { return item; + } } } @@ -700,7 +704,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL); } else if (flag & UI_ITEM_R_EVENT) { - uiDefButR_prop(block, UI_BTYPE_KEY_EVENT, 0, name, x, y, w, h, ptr, prop, index, 0, 0, -1, -1, NULL); + but = uiDefButR_prop(block, UI_BTYPE_KEY_EVENT, 0, name, x, y, w, h, ptr, prop, index, 0, 0, -1, -1, NULL); } else if (flag & UI_ITEM_R_FULL_EVENT) { if (RNA_struct_is_a(ptr->type, &RNA_KeyMapItem)) { @@ -2228,6 +2232,10 @@ static void ui_litem_layout_column(uiLayout *litem, bool is_box) if (item->next && (!is_box || item != litem->items.first)) y -= litem->space; + + if (is_box) { + item->flag |= UI_ITEM_BOX_ITEM; + } } litem->h = litem->y - y; @@ -3188,8 +3196,18 @@ static void ui_item_layout(uiItem *item) break; } - for (subitem = litem->items.first; subitem; subitem = subitem->next) + for (subitem = litem->items.first; subitem; subitem = subitem->next) { + if (item->flag & UI_ITEM_BOX_ITEM) { + subitem->flag |= UI_ITEM_BOX_ITEM; + } ui_item_layout(subitem); + } + } + else { + if (item->flag & UI_ITEM_BOX_ITEM) { + uiButtonItem *bitem = (uiButtonItem *)item; + bitem->but->drawflag |= UI_BUT_BOX_ITEM; + } } } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 738ebfcc5c2..640673857df 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2960,8 +2960,8 @@ uiPieMenu *UI_pie_menu_begin(struct bContext *C, const char *title, int icon, co pie->block_radial->puphash = ui_popup_menu_hash(title); pie->block_radial->flag |= UI_BLOCK_RADIAL; - /* if pie is spawned by a left click, it is always assumed to be click style */ - if (event->type == LEFTMOUSE) { + /* if pie is spawned by a left click, release or click event, it is always assumed to be click style */ + if (event->type == LEFTMOUSE || ELEM(event->val, KM_RELEASE, KM_CLICK)) { pie->block_radial->pie_data.flags |= UI_PIE_CLICK_STYLE; pie->block_radial->pie_data.event = EVENT_NONE; win->lock_pie_event = EVENT_NONE; diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 869be844b05..f0317087ddc 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -347,7 +347,7 @@ int UI_icon_from_report_type(int type) */ int UI_calc_float_precision(int prec, double value) { - static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = {1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7}; + static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = {1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6}; static const double max_pow = 10000000.0; /* pow(10, UI_PRECISION_FLOAT_MAX) */ BLI_assert(prec <= UI_PRECISION_FLOAT_MAX); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 8adcca8c7cd..73e549e703b 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -3811,11 +3811,15 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct switch (but->type) { case UI_BTYPE_LABEL: - if (but->block->flag & UI_BLOCK_LOOP) - widget_draw_text_icon(&style->widgetlabel, &tui->wcol_menu_back, but, rect); - else { - wt = widget_type(UI_WTYPE_LABEL); - fstyle = &style->widgetlabel; + wt = widget_type(UI_WTYPE_LABEL); + fstyle = &style->widgetlabel; + if (but->drawflag & UI_BUT_BOX_ITEM) { + wt->wcol_theme = &tui->wcol_box; + wt->state = widget_state; + } + else if (but->block->flag & UI_BLOCK_LOOP) { + wt->wcol_theme = &tui->wcol_menu_back; + wt->state = widget_state; } break; diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index cf35f4d895b..274429d5390 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -2912,6 +2912,24 @@ void init_userdef_do_versions(void) } } + if (!USER_VERSION_ATLEAST(278, 6)) { + /* Clear preference flags for re-use. */ + U.flag &= ~( + USER_FLAG_DEPRECATED_1 | USER_FLAG_DEPRECATED_2 | USER_FLAG_DEPRECATED_3 | + USER_FLAG_DEPRECATED_6 | USER_FLAG_DEPRECATED_7 | + USER_FLAG_DEPRECATED_9 | USER_FLAG_DEPRECATED_10); + U.uiflag &= ~( + USER_UIFLAG_DEPRECATED_7); + U.transopts &= ~( + USER_TR_DEPRECATED_2 | USER_TR_DEPRECATED_3 | USER_TR_DEPRECATED_4 | + USER_TR_DEPRECATED_6 | USER_TR_DEPRECATED_7); + U.gameflags &= ~( + USER_GL_RENDER_DEPRECATED_0 | USER_GL_RENDER_DEPRECATED_1 | + USER_GL_RENDER_DEPRECATED_3 | USER_GL_RENDER_DEPRECATED_4); + + U.uiflag |= USER_LOCK_CURSOR_ADJUST; + } + /** * Include next version bump. * diff --git a/source/blender/editors/io/CMakeLists.txt b/source/blender/editors/io/CMakeLists.txt index b3bbce939a5..4d3f106a5d6 100644 --- a/source/blender/editors/io/CMakeLists.txt +++ b/source/blender/editors/io/CMakeLists.txt @@ -24,6 +24,7 @@ set(INC ../../blenlib ../../blentranslation ../../bmesh + ../../depsgraph ../../makesdna ../../makesrna ../../windowmanager diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index ba3966d5af6..f9297c58cbb 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -56,6 +56,8 @@ #include "io_collada.h" +#include "DEG_depsgraph.h" + static int wm_collada_export_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { if (!RNA_struct_property_is_set(op->ptr, "filepath")) { @@ -78,6 +80,7 @@ static int wm_collada_export_invoke(bContext *C, wmOperator *op, const wmEvent * /* function used for WM_OT_save_mainfile too */ static int wm_collada_export_exec(bContext *C, wmOperator *op) { + EvaluationContext eval_ctx; char filepath[FILE_MAX]; int apply_modifiers; int export_mesh_type; @@ -103,6 +106,8 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) int export_count; + CTX_data_eval_ctx(C, &eval_ctx); + if (!RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); return OPERATOR_CANCELLED; @@ -156,7 +161,8 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) ED_object_editmode_load(CTX_data_edit_object(C)); - export_count = collada_export(CTX_data_scene(C), + export_count = collada_export(&eval_ctx, + CTX_data_scene(C), CTX_data_scene_layer(C), filepath, apply_modifiers, diff --git a/source/blender/editors/manipulator_library/manipulator_library_intern.h b/source/blender/editors/manipulator_library/manipulator_library_intern.h index ce71017e7bc..a22afda8730 100644 --- a/source/blender/editors/manipulator_library/manipulator_library_intern.h +++ b/source/blender/editors/manipulator_library/manipulator_library_intern.h @@ -87,8 +87,11 @@ void manipulator_property_value_reset( void manipulator_color_get( const struct wmManipulator *mpr, const bool highlight, - float r_col[]); + float r_color[4]); +bool manipulator_window_project_2d( + bContext *C, const struct wmManipulator *mpr, const float mval[2], int axis, bool use_offset, + float r_co[2]); /* -------------------------------------------------------------------- */ /* Manipulator drawing */ diff --git a/source/blender/editors/manipulator_library/manipulator_library_presets.c b/source/blender/editors/manipulator_library/manipulator_library_presets.c index d8e66f40be0..e8111bda657 100644 --- a/source/blender/editors/manipulator_library/manipulator_library_presets.c +++ b/source/blender/editors/manipulator_library/manipulator_library_presets.c @@ -127,7 +127,7 @@ void ED_manipulator_draw_preset_circle( } void ED_manipulator_draw_preset_facemap( - const struct wmManipulator *mpr, struct Scene *scene, Object *ob, const int facemap, int select_id) + const bContext *C, const struct wmManipulator *mpr, struct Scene *scene, Object *ob, const int facemap, int select_id) { const bool is_select = (select_id != -1); const bool is_highlight = is_select && (mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT) != 0; @@ -141,7 +141,7 @@ void ED_manipulator_draw_preset_facemap( gpuPushMatrix(); gpuMultMatrix(ob->obmat); - ED_draw_object_facemap(scene, ob, color, facemap); + ED_draw_object_facemap(C, scene, ob, color, facemap); gpuPopMatrix(); if (is_select) { diff --git a/source/blender/editors/manipulator_library/manipulator_library_utils.c b/source/blender/editors/manipulator_library/manipulator_library_utils.c index 9c182fcf4bc..58999a82bba 100644 --- a/source/blender/editors/manipulator_library/manipulator_library_utils.c +++ b/source/blender/editors/manipulator_library/manipulator_library_utils.c @@ -36,6 +36,11 @@ #include "BLI_math.h" #include "BLI_listbase.h" +#include "DNA_view3d_types.h" +#include "DNA_screen_types.h" + +#include "ED_view3d.h" + #include "RNA_access.h" #include "WM_api.h" @@ -121,9 +126,13 @@ void manipulator_property_data_update( if (constrained) { if ((data->flag & MANIPULATOR_CUSTOM_RANGE_SET) == 0) { float range[2]; - WM_manipulator_target_property_range_get(mpr, mpr_prop, range); - data->range = range[1] - range[0]; - data->min = range[0]; + if (WM_manipulator_target_property_range_get(mpr, mpr_prop, range)) { + data->range = range[1] - range[0]; + data->min = range[0]; + } + else { + BLI_assert(0); + } } data->offset = manipulator_offset_from_value_constr(data->range_fac, data->min, data->range, value, inverted); } @@ -152,3 +161,58 @@ void manipulator_color_get( copy_v4_v4(r_col, mpr->color); } } + +/* -------------------------------------------------------------------- */ + +/** + * Takes mouse coordinates and returns them in relation to the manipulator. + * Both 2D & 3D supported, use so we can use 2D manipulators in the 3D view. + */ +bool manipulator_window_project_2d( + bContext *C, const struct wmManipulator *mpr, const float mval[2], int axis, bool use_offset, + float r_co[2]) +{ + float mat[4][4]; + if (use_offset) { + mul_m4_series(mat, mpr->matrix_space, mpr->matrix_basis, mpr->matrix_offset); + } + else { + mul_m4_series(mat, mpr->matrix_space, mpr->matrix_basis); + } + + /* rotate mouse in relation to the center and relocate it */ + if (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) { + /* For 3d views, transform 2D mouse pos onto plane. */ + View3D *v3d = CTX_wm_view3d(C); + ARegion *ar = CTX_wm_region(C); + + float plane[4]; + + plane_from_point_normal_v3(plane, mat[3], mat[2]); + + float ray_origin[3], ray_direction[3]; + + if (ED_view3d_win_to_ray(ar, v3d, mval, ray_origin, ray_direction, false)) { + float lambda; + if (isect_ray_plane_v3(ray_origin, ray_direction, plane, &lambda, true)) { + float co[3]; + madd_v3_v3v3fl(co, ray_origin, ray_direction, lambda); + float imat[4][4]; + invert_m4_m4(imat, mat); + mul_m4_v3(imat, co); + r_co[0] = co[(axis + 1) % 3]; + r_co[1] = co[(axis + 2) % 3]; + return true; + } + } + return false; + } + else { + float co[3] = {mval[0], mval[1], 0.0f}; + float imat[4][4]; + invert_m4_m4(imat, mat); + mul_m4_v3(imat, co); + copy_v2_v2(r_co, co); + return true; + } +} diff --git a/source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c index d402ab0b6f1..59a1e08d95a 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c @@ -121,7 +121,7 @@ static void manipulator_arrow2d_draw(const bContext *UNUSED(C), wmManipulator *m static void manipulator_arrow2d_setup(wmManipulator *mpr) { - mpr->flag |= WM_MANIPULATOR_DRAW_ACTIVE; + mpr->flag |= WM_MANIPULATOR_DRAW_MODAL; } static void manipulator_arrow2d_invoke( diff --git a/source/blender/editors/manipulator_library/manipulator_types/arrow3d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/arrow3d_manipulator.c index e95800f3db1..923eca27e7c 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/arrow3d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/arrow3d_manipulator.c @@ -36,6 +36,8 @@ * - `matrix[0]` is derived from Y and Z. * - `matrix[1]` is 'up' for manipulator types that have an up. * - `matrix[2]` is the arrow direction (for all arrowes). + * + * TODO: use matrix_space */ #include "BIF_gl.h" @@ -220,9 +222,9 @@ static void arrow_draw_intern(ArrowManipulator3D *arrow, const bool select, cons static void manipulator_arrow_draw_select( const bContext *UNUSED(C), wmManipulator *mpr, - int selectionbase) + int select_id) { - GPU_select_load_id(selectionbase); + GPU_select_load_id(select_id); arrow_draw_intern((ArrowManipulator3D *)mpr, true, false); } @@ -235,7 +237,9 @@ static void manipulator_arrow_draw(const bContext *UNUSED(C), wmManipulator *mpr * Calculate arrow offset independent from prop min value, * meaning the range will not be offset by min value first. */ -static void manipulator_arrow_modal(bContext *C, wmManipulator *mpr, const wmEvent *event, const int flag) +static void manipulator_arrow_modal( + bContext *C, wmManipulator *mpr, const wmEvent *event, + eWM_ManipulatorTweak tweak_flag) { ArrowManipulator3D *arrow = (ArrowManipulator3D *)mpr; ManipulatorInteraction *inter = mpr->interaction_data; @@ -267,7 +271,7 @@ static void manipulator_arrow_modal(bContext *C, wmManipulator *mpr, const wmEve /* first determine if view vector is really close to the direction. If it is, we use * vertical movement to determine offset, just like transform system does */ - if (RAD2DEG(acos(dot_v3v3(viewvec, arrow->manipulator.matrix_basis[2]))) > 5.0f) { + if (RAD2DEGF(acosf(dot_v3v3(viewvec, arrow->manipulator.matrix_basis[2]))) > 5.0f) { /* multiply to projection space */ mul_m4_v4(rv3d->persmat, orig_origin); mul_v4_fl(orig_origin, 1.0f / orig_origin[3]); @@ -314,13 +318,13 @@ static void manipulator_arrow_modal(bContext *C, wmManipulator *mpr, const wmEve const float plane_offset = dot_v3v3(plane, offset); const float plane_dir = dot_v3v3(plane, arrow->manipulator.matrix_basis[2]); const float fac = (plane_dir != 0.0f) ? (plane_offset / plane_dir) : 0.0f; - facdir = (fac < 0.0) ? -1.0 : 1.0; + facdir = (fac < 0.0f) ? -1.0f : 1.0f; if (isfinite(fac)) { mul_v3_v3fl(offset, arrow->manipulator.matrix_basis[2], fac); } } else { - facdir = (m_diff[1] < 0.0) ? -1.0 : 1.0; + facdir = (m_diff[1] < 0.0f) ? -1.0f : 1.0f; } @@ -334,7 +338,7 @@ static void manipulator_arrow_modal(bContext *C, wmManipulator *mpr, const wmEve const int draw_options = RNA_enum_get(arrow->manipulator.ptr, "draw_options"); const bool constrained = (draw_options & ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED) != 0; const bool inverted = (draw_options & ED_MANIPULATOR_ARROW_STYLE_INVERTED) != 0; - const bool use_precision = (flag & WM_MANIPULATOR_TWEAK_PRECISE) != 0; + const bool use_precision = (tweak_flag & WM_MANIPULATOR_TWEAK_PRECISE) != 0; float value = manipulator_value_from_offset(data, inter, ofs_new, constrained, inverted, use_precision); WM_manipulator_target_property_value_set(C, mpr, mpr_prop, value); @@ -356,7 +360,7 @@ static void manipulator_arrow_setup(wmManipulator *mpr) { ArrowManipulator3D *arrow = (ArrowManipulator3D *)mpr; - arrow->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE; + arrow->manipulator.flag |= WM_MANIPULATOR_DRAW_MODAL; arrow->data.range_fac = 1.0f; } diff --git a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c index 973f487fd82..ee8d0e85dfd 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c @@ -42,11 +42,13 @@ #include "BLI_rect.h" #include "ED_screen.h" +#include "ED_view3d.h" #include "ED_manipulator_library.h" #include "GPU_matrix.h" #include "GPU_shader.h" #include "GPU_immediate.h" +#include "GPU_select.h" #include "MEM_guardedalloc.h" @@ -56,6 +58,9 @@ #include "WM_api.h" #include "WM_types.h" +/* own includes */ +#include "../manipulator_library_intern.h" + /* wmManipulator->highlight_part */ enum { ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE = 1, @@ -68,7 +73,6 @@ enum { #define MANIPULATOR_RECT_MIN_WIDTH 15.0f #define MANIPULATOR_RESIZER_WIDTH 20.0f - /* -------------------------------------------------------------------- */ static void rect_transform_draw_corners( @@ -168,7 +172,7 @@ static void rect_transform_draw_interaction( uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - glLineWidth(line_width + 3.0); + glLineWidth(line_width + 3.0f); immBegin(GWN_PRIM_LINE_STRIP, 3); immAttrib3f(color, 0.0f, 0.0f, 0.0f); @@ -189,16 +193,15 @@ static void rect_transform_draw_interaction( immUnbindProgram(); } -static void manipulator_rect_transform_draw(const bContext *UNUSED(C), wmManipulator *mpr) +static void manipulator_rect_transform_draw_intern( + wmManipulator *mpr, const bool select, const bool highlight, const int select_id) { + const bool use_clamp = (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) == 0; float dims[2]; RNA_float_get_array(mpr->ptr, "dimensions", dims); float w = dims[0]; float h = dims[1]; - float scale[2]; - RNA_float_get_array(mpr->ptr, "scale", scale); - const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); float aspx = 1.0f, aspy = 1.0f; @@ -212,14 +215,9 @@ static void manipulator_rect_transform_draw(const bContext *UNUSED(C), wmManipul }; gpuPushMatrix(); + gpuMultMatrix(mpr->matrix_space); gpuMultMatrix(mpr->matrix_basis); gpuMultMatrix(mpr->matrix_offset); - if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) { - gpuScaleUniform(scale[0]); - } - else { - gpuScale2fv(scale); - } if (w > h) { aspx = h / w; @@ -227,9 +225,15 @@ static void manipulator_rect_transform_draw(const bContext *UNUSED(C), wmManipul else { aspy = w / h; } - w = min_ff(aspx * w / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH / scale[0]); - h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH / - ((transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) ? scale[0] : scale[1])); + + if (use_clamp) { + w = min_ff(aspx * w / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH); + h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH); + } + else { + /* Corner size. */ + w = h = min_ff(w * aspx, h * aspy) / 10.0f; + } /* corner manipulators */ glLineWidth(mpr->line_width + 3.0f); @@ -237,20 +241,62 @@ static void manipulator_rect_transform_draw(const bContext *UNUSED(C), wmManipul rect_transform_draw_corners(&r, w, h, (const float[3]){0, 0, 0}); /* corner manipulators */ - glLineWidth(mpr->line_width); - rect_transform_draw_corners(&r, w, h, mpr->color); + { + float col[4]; + manipulator_color_get(mpr, highlight, col); + glLineWidth(mpr->line_width); + rect_transform_draw_corners(&r, w, h, col); + } - rect_transform_draw_interaction( - mpr->color, mpr->highlight_part, half_w, half_h, - w, h, mpr->line_width); + if (select) { + if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE) { + int scale_parts[] = { + ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT, + ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT, + ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP, + ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN, + }; + for (int i = 0; i < ARRAY_SIZE(scale_parts); i++) { + GPU_select_load_id(select_id | scale_parts[i]); + rect_transform_draw_interaction( + mpr->color, scale_parts[i], half_w, half_h, + w, h, mpr->line_width); + } + } + } + else { + rect_transform_draw_interaction( + mpr->color, mpr->highlight_part, half_w, half_h, + w, h, mpr->line_width); + } glLineWidth(1.0); gpuPopMatrix(); } +/** + * For when we want to draw 2d cage in 3d views. + */ +static void manipulator_rect_transform_draw_select(const bContext *UNUSED(C), wmManipulator *mpr, int select_id) +{ + manipulator_rect_transform_draw_intern(mpr, true, false, select_id); +} + +static void manipulator_rect_transform_draw(const bContext *UNUSED(C), wmManipulator *mpr) +{ + const bool is_highlight = (mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT) != 0; + manipulator_rect_transform_draw_intern(mpr, false, is_highlight, -1); +} + static int manipulator_rect_transform_get_cursor(wmManipulator *mpr) { - switch (mpr->highlight_part) { + int highlight_part = mpr->highlight_part; + + if (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) { + return BC_NSEW_SCROLLCURSOR; + } + + switch (highlight_part) { case ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE: return BC_HANDCURSOR; case ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT: @@ -265,13 +311,10 @@ static int manipulator_rect_transform_get_cursor(wmManipulator *mpr) } static int manipulator_rect_transform_test_select( - bContext *UNUSED(C), wmManipulator *mpr, const wmEvent *event) + bContext *C, wmManipulator *mpr, const wmEvent *event) { - const float mouse[2] = {event->mval[0], event->mval[1]}; //float matrot[2][2]; float point_local[2]; - float scale[2]; - RNA_float_get_array(mpr->ptr, "scale", scale); float dims[2]; RNA_float_get_array(mpr->ptr, "dimensions", dims); float w = dims[0]; @@ -280,31 +323,21 @@ static int manipulator_rect_transform_test_select( float half_h = h / 2.0f; float aspx = 1.0f, aspy = 1.0f; - const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); - - /* rotate mouse in relation to the center and relocate it */ - sub_v2_v2v2(point_local, mouse, mpr->matrix_basis[3]); - point_local[0] -= mpr->matrix_offset[3][0]; - point_local[1] -= mpr->matrix_offset[3][1]; - //rotate_m2(matrot, -cage->transform.rotation); - - if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) { - mul_v2_fl(point_local, 1.0f / scale[0]); - } - else { - point_local[0] /= scale[0]; - point_local[1] /= scale[0]; + if (manipulator_window_project_2d( + C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) + { + return 0; } + const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); if (dims[0] > dims[1]) { aspx = h / w; } else { aspy = w / h; } - w = min_ff(aspx * w / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH / scale[0]); - h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH / - ((transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) ? scale[0] : scale[1])); + w = min_ff(aspx * w / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH); + h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH); rctf r; @@ -369,162 +402,195 @@ static int manipulator_rect_transform_test_select( typedef struct RectTransformInteraction { float orig_mouse[2]; - float orig_offset[2]; - float orig_scale[2]; + float orig_matrix_offset[4][4]; } RectTransformInteraction; static bool manipulator_rect_transform_get_prop_value( wmManipulator *mpr, wmManipulatorProperty *mpr_prop, float *value) { - PropertyType type = RNA_property_type(mpr_prop->prop); - - if (type != PROP_FLOAT) { - fprintf(stderr, "Rect Transform manipulator can only be bound to float properties"); - return false; + if (STREQ(mpr_prop->type->idname, "offset")) { + WM_manipulator_target_property_value_get_array(mpr, mpr_prop, value); } - else { - if (STREQ(mpr_prop->type->idname, "offset")) { - if (RNA_property_array_length(&mpr_prop->ptr, mpr_prop->prop) != 2) { - fprintf(stderr, "Rect Transform manipulator offset not only be bound to array float property"); - return false; - } - RNA_property_float_get_array(&mpr_prop->ptr, mpr_prop->prop, value); - } - else if (STREQ(mpr_prop->type->idname, "scale")) { - const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); - if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) { - *value = RNA_property_float_get(&mpr_prop->ptr, mpr_prop->prop); + else if (STREQ(mpr_prop->type->idname, "scale")) { + const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); + if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) { + if (WM_manipulator_target_property_array_length(mpr, mpr_prop) == 2) { + WM_manipulator_target_property_value_get_array(mpr, mpr_prop, value); } else { - if (RNA_property_array_length(&mpr_prop->ptr, mpr_prop->prop) != 2) { - fprintf(stderr, "Rect Transform manipulator scale not only be bound to array float property"); - return false; - } - RNA_property_float_get_array(&mpr_prop->ptr, mpr_prop->prop, value); + *value = WM_manipulator_target_property_value_get(mpr, mpr_prop); + value[1] = value[0]; } } else { - BLI_assert(0); + WM_manipulator_target_property_value_get_array(mpr, mpr_prop, value); } } + else { + BLI_assert(0); + } return true; } static void manipulator_rect_transform_setup(wmManipulator *mpr) { - mpr->flag |= WM_MANIPULATOR_DRAW_ACTIVE; + mpr->flag |= WM_MANIPULATOR_DRAW_MODAL; } static void manipulator_rect_transform_invoke( - bContext *UNUSED(C), wmManipulator *mpr, const wmEvent *event) + bContext *C, wmManipulator *mpr, const wmEvent *event) { RectTransformInteraction *data = MEM_callocN(sizeof(RectTransformInteraction), "cage_interaction"); - float scale[2]; - RNA_float_get_array(mpr->ptr, "scale", scale); - - copy_v2_v2(data->orig_offset, mpr->matrix_offset[3]); - copy_v2_v2(data->orig_scale, scale); + copy_m4_m4(data->orig_matrix_offset, mpr->matrix_offset); - data->orig_mouse[0] = event->mval[0]; - data->orig_mouse[1] = event->mval[1]; + if (manipulator_window_project_2d( + C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, data->orig_mouse) == 0) + { + zero_v2(data->orig_mouse); + } mpr->interaction_data = data; } static void manipulator_rect_transform_modal( bContext *C, wmManipulator *mpr, const wmEvent *event, - const int UNUSED(flag)) + eWM_ManipulatorTweak UNUSED(tweak_flag)) { + const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); + const bool pivot_center = (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_TRANSLATE) == 0; RectTransformInteraction *data = mpr->interaction_data; +#if 0 /* needed here as well in case clamping occurs */ - const float orig_ofx = mpr->matrix_offset[3][0], orig_ofy = mpr->matrix_offset[3][1]; + const bool use_clamp = (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) == 0; + const float orig_ofx = mpr->matrix_offset[3][0]; + const float orig_ofy = mpr->matrix_offset[3][1]; +#endif - const float valuex = (event->mval[0] - data->orig_mouse[0]); - const float valuey = (event->mval[1] - data->orig_mouse[1]); + float point_local[2]; - const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); + if (manipulator_window_project_2d( + C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, point_local) == false) + { + return; + } + + float value_x = (point_local[0] - data->orig_mouse[0]); + float value_y = (point_local[1] - data->orig_mouse[1]); float dims[2]; RNA_float_get_array(mpr->ptr, "dimensions", dims); - float scale[2]; - RNA_float_get_array(mpr->ptr, "scale", scale); + const float orig_scale[2] = {data->orig_matrix_offset[0][0], data->orig_matrix_offset[1][1]}; + const float *orig_offset = data->orig_matrix_offset[3]; + + float scale[2] = {mpr->matrix_offset[0][0], mpr->matrix_offset[1][1]}; + float *offset = mpr->matrix_offset[3]; if (mpr->highlight_part == ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE) { - mpr->matrix_offset[3][0] = data->orig_offset[0] + valuex; - mpr->matrix_offset[3][1] = data->orig_offset[1] + valuey; + offset[0] = orig_offset[0] + value_x; + offset[1] = orig_offset[1] + value_y; } else if (mpr->highlight_part == ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT) { - mpr->matrix_offset[3][0] = data->orig_offset[0] + valuex / 2.0; - scale[0] = (dims[0] * data->orig_scale[0] - valuex) / dims[0]; + value_x = min_ff(value_x, (dims[0] * orig_scale[0]) * (pivot_center ? 2 : 1)); + if (pivot_center == false) { + offset[0] = orig_offset[0] + value_x / 2.0f; + } + scale[0] = (dims[0] * orig_scale[0] - value_x) / dims[0]; } else if (mpr->highlight_part == ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT) { - mpr->matrix_offset[3][0] = data->orig_offset[0] + valuex / 2.0; - scale[0] = (dims[0] * data->orig_scale[0] + valuex) / dims[0]; + value_x = max_ff(value_x, (dims[0] * orig_scale[0]) * (pivot_center ? -2 : -1)); + if (pivot_center == false) { + offset[0] = orig_offset[0] + value_x / 2.0f; + } + scale[0] = (dims[0] * orig_scale[0] + value_x) / dims[0]; } else if (mpr->highlight_part == ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN) { - mpr->matrix_offset[3][1] = data->orig_offset[1] + valuey / 2.0; - - if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) { - scale[0] = (dims[1] * data->orig_scale[0] - valuey) / dims[1]; - } - else { - scale[1] = (dims[1] * data->orig_scale[1] - valuey) / dims[1]; + int a = (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) ? 0 : 1; + value_y = min_ff(value_y, (dims[1] * orig_scale[a]) * (pivot_center ? 2 : 1)); + if (pivot_center == false) { + offset[1] = orig_offset[1] + value_y / 2.0f; } + scale[a] = (dims[1] * orig_scale[a] - value_y) / dims[1]; } else if (mpr->highlight_part == ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP) { - mpr->matrix_offset[3][1] = data->orig_offset[1] + valuey / 2.0; - - if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) { - scale[0] = (dims[1] * data->orig_scale[0] + valuey) / dims[1]; - } - else { - scale[1] = (dims[1] * data->orig_scale[1] + valuey) / dims[1]; + int a = (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) ? 0 : 1; + value_y = max_ff(value_y, (dims[1] * orig_scale[a]) * (pivot_center ? -2 : -1)); + if (pivot_center == false) { + offset[1] = orig_offset[1] + value_y / 2.0f; } + scale[a] = (dims[1] * orig_scale[a] + value_y) / dims[1]; + } + else { + BLI_assert(0); } + /* TODO(campbell): Complicates things too much since not all scales are in the same space. */ +#if 0 /* clamping - make sure manipulator is at least 5 pixels wide */ - if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) { - if (scale[0] < MANIPULATOR_RECT_MIN_WIDTH / dims[1] || - scale[0] < MANIPULATOR_RECT_MIN_WIDTH / dims[0]) - { + if (use_clamp == false) { + /* pass */ + } + else if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) { + if (scale[0] < MANIPULATOR_RECT_MIN_WIDTH / max_ff(dims[0], dims[1])) { scale[0] = max_ff(MANIPULATOR_RECT_MIN_WIDTH / dims[1], MANIPULATOR_RECT_MIN_WIDTH / dims[0]); - mpr->matrix_offset[3][0] = orig_ofx; - mpr->matrix_offset[3][1] = orig_ofy; + offset[0] = orig_ofx; + offset[1] = orig_ofy; } } else { if (scale[0] < MANIPULATOR_RECT_MIN_WIDTH / dims[0]) { scale[0] = MANIPULATOR_RECT_MIN_WIDTH / dims[0]; - mpr->matrix_offset[3][0] = orig_ofx; + offset[0] = orig_ofx; } if (scale[1] < MANIPULATOR_RECT_MIN_WIDTH / dims[1]) { scale[1] = MANIPULATOR_RECT_MIN_WIDTH / dims[1]; - mpr->matrix_offset[3][1] = orig_ofy; + offset[1] = orig_ofy; + } + } +#endif + + { + wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "scale"); + if (mpr_prop->type != NULL) { + float range[2]; + if (WM_manipulator_target_property_range_get(mpr, mpr_prop, range)) { + CLAMP(scale[0], range[0], range[1]); + CLAMP(scale[1], range[0], range[1]); + } } } - RNA_float_set_array(mpr->ptr, "scale", scale); + /* Needed for when we're uniform transforming a 2D vector and need to write both. */ + if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) { + scale[1] = scale[0]; + } + + mpr->matrix_offset[0][0] = scale[0]; + mpr->matrix_offset[1][1] = scale[1]; wmManipulatorProperty *mpr_prop; mpr_prop = WM_manipulator_target_property_find(mpr, "offset"); - if (mpr_prop->prop != NULL) { - RNA_property_float_set_array(&mpr_prop->ptr, mpr_prop->prop, mpr->matrix_offset[3]); - RNA_property_update(C, &mpr_prop->ptr, mpr_prop->prop); + if (mpr_prop->type != NULL) { + WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, offset); } mpr_prop = WM_manipulator_target_property_find(mpr, "scale"); - if (mpr_prop->prop != NULL) { + if (mpr_prop->type != NULL) { if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) { - RNA_property_float_set(&mpr_prop->ptr, mpr_prop->prop, scale[0]); + scale[1] = scale[0]; + if (WM_manipulator_target_property_array_length(mpr, mpr_prop) == 2) { + WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, scale); + } + else { + WM_manipulator_target_property_value_set(C, mpr, mpr_prop, scale[0]); + } } else { - RNA_property_float_set_array(&mpr_prop->ptr, mpr_prop->prop, scale); + WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, scale); } - RNA_property_update(C, &mpr_prop->ptr, mpr_prop->prop); } /* tag the region for redraw */ @@ -538,8 +604,9 @@ static void manipulator_rect_transform_property_update(wmManipulator *mpr, wmMan } else if (STREQ(mpr_prop->type->idname, "scale")) { float scale[2]; - RNA_float_get_array(mpr->ptr, "scale", scale); manipulator_rect_transform_get_prop_value(mpr, mpr_prop, scale); + mpr->matrix_offset[0][0] = scale[0]; + mpr->matrix_offset[1][1] = scale[1]; } else { BLI_assert(0); @@ -557,22 +624,28 @@ static void manipulator_rect_transform_exit(bContext *C, wmManipulator *mpr, con /* reset properties */ mpr_prop = WM_manipulator_target_property_find(mpr, "offset"); - if (mpr_prop->prop != NULL) { - RNA_property_float_set_array(&mpr_prop->ptr, mpr_prop->prop, data->orig_offset); - RNA_property_update(C, &mpr_prop->ptr, mpr_prop->prop); + if (mpr_prop->type != NULL) { + WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, data->orig_matrix_offset[3]); } mpr_prop = WM_manipulator_target_property_find(mpr, "scale"); - if (mpr_prop->prop != NULL) { + if (mpr_prop->type != NULL) { + const float orig_scale[2] = {data->orig_matrix_offset[0][0], data->orig_matrix_offset[1][1]}; const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) { - RNA_property_float_set(&mpr_prop->ptr, mpr_prop->prop, data->orig_scale[0]); + if (WM_manipulator_target_property_array_length(mpr, mpr_prop) == 2) { + WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, orig_scale); + } + else { + WM_manipulator_target_property_value_set(C, mpr, mpr_prop, orig_scale[0]); + } } else { - RNA_property_float_set_array(&mpr_prop->ptr, mpr_prop->prop, data->orig_scale); + WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, orig_scale); } - RNA_property_update(C, &mpr_prop->ptr, mpr_prop->prop); } + + copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset); } @@ -588,6 +661,7 @@ static void MANIPULATOR_WT_cage_2d(wmManipulatorType *wt) /* api callbacks */ wt->draw = manipulator_rect_transform_draw; + wt->draw_select = manipulator_rect_transform_draw_select; wt->setup = manipulator_rect_transform_setup; wt->invoke = manipulator_rect_transform_invoke; wt->property_update = manipulator_rect_transform_property_update; @@ -606,14 +680,12 @@ static void MANIPULATOR_WT_cage_2d(wmManipulatorType *wt) {ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM, "SCALE_UNIFORM", 0, "Scale Uniform", ""}, {0, NULL, 0, NULL, NULL} }; - static float scale_default[2] = {1.0f, 1.0f}; - RNA_def_float_vector(wt->srna, "scale", 2, scale_default, 0, FLT_MAX, "Scale", "", 0.0f, FLT_MAX); - RNA_def_float_vector(wt->srna, "dimensions", 2, NULL, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX); + static float unit_v2[2] = {1.0f, 1.0f}; + RNA_def_float_vector(wt->srna, "dimensions", 2, unit_v2, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX); RNA_def_enum_flag(wt->srna, "transform", rna_enum_transform, 0, "Transform Options", ""); - WM_manipulatortype_target_property_def(wt, "offset", PROP_FLOAT, 1); + WM_manipulatortype_target_property_def(wt, "offset", PROP_FLOAT, 2); WM_manipulatortype_target_property_def(wt, "scale", PROP_FLOAT, 2); - WM_manipulatortype_target_property_def(wt, "scale_uniform", PROP_FLOAT, 1); } void ED_manipulatortypes_cage_2d(void) diff --git a/source/blender/editors/manipulator_library/manipulator_types/dial3d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/dial3d_manipulator.c index 0b979758688..742b4c70613 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/dial3d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/dial3d_manipulator.c @@ -36,6 +36,8 @@ * - `matrix[0]` is derived from Y and Z. * - `matrix[1]` is 'up' when DialManipulator.use_start_y_axis is set. * - `matrix[2]` is the axis the dial rotates around (all dials). + * + * TODO: use matrix_space */ #include "BIF_gl.h" @@ -71,7 +73,9 @@ /* to use custom dials exported to geom_dial_manipulator.c */ // #define USE_MANIPULATOR_CUSTOM_DIAL -static void manipulator_dial_modal(bContext *C, wmManipulator *mpr, const wmEvent *event, const int flag); +static void manipulator_dial_modal( + bContext *C, wmManipulator *mpr, const wmEvent *event, + eWM_ManipulatorTweak tweak_flag); typedef struct DialInteraction { float init_mval[2]; @@ -286,7 +290,7 @@ static void dial_draw_intern( /* draw rotation indicator arc first */ if ((mpr->flag & WM_MANIPULATOR_DRAW_VALUE) && - (mpr->state & WM_MANIPULATOR_STATE_ACTIVE)) + (mpr->state & WM_MANIPULATOR_STATE_MODAL)) { const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f}; /* coordinate at which the arc drawing will be started */ @@ -315,7 +319,7 @@ static void dial_draw_intern( } } - angle_ofs += M_PI; + angle_ofs += (float)M_PI; } } @@ -325,7 +329,7 @@ static void dial_draw_intern( gpuPopMatrix(); } -static void manipulator_dial_draw_select(const bContext *C, wmManipulator *mpr, int selectionbase) +static void manipulator_dial_draw_select(const bContext *C, wmManipulator *mpr, int select_id) { float clip_plane_buf[4]; const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); @@ -341,7 +345,7 @@ static void manipulator_dial_draw_select(const bContext *C, wmManipulator *mpr, glEnable(GL_CLIP_DISTANCE0); } - GPU_select_load_id(selectionbase); + GPU_select_load_id(select_id); dial_draw_intern(C, mpr, true, false, clip_plane); if (clip_plane) { @@ -351,11 +355,11 @@ static void manipulator_dial_draw_select(const bContext *C, wmManipulator *mpr, static void manipulator_dial_draw(const bContext *C, wmManipulator *mpr) { - const bool active = mpr->state & WM_MANIPULATOR_STATE_ACTIVE; - const bool highlight = (mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT) != 0; + const bool is_modal = mpr->state & WM_MANIPULATOR_STATE_MODAL; + const bool is_highlight = (mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT) != 0; float clip_plane_buf[4]; const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); - float *clip_plane = (!active && (draw_options & ED_MANIPULATOR_DIAL_DRAW_FLAG_CLIP)) ? clip_plane_buf : NULL; + float *clip_plane = (!is_modal && (draw_options & ED_MANIPULATOR_DIAL_DRAW_FLAG_CLIP)) ? clip_plane_buf : NULL; /* enable clipping if needed */ if (clip_plane) { @@ -364,13 +368,13 @@ static void manipulator_dial_draw(const bContext *C, wmManipulator *mpr) copy_v3_v3(clip_plane, rv3d->viewinv[2]); clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], mpr->matrix_basis[3]); - clip_plane[3] -= 0.02 * mpr->scale_final; + clip_plane[3] -= 0.02f * mpr->scale_final; glEnable(GL_CLIP_DISTANCE0); } glEnable(GL_BLEND); - dial_draw_intern(C, mpr, false, highlight, clip_plane); + dial_draw_intern(C, mpr, false, is_highlight, clip_plane); glDisable(GL_BLEND); if (clip_plane) { @@ -378,7 +382,9 @@ static void manipulator_dial_draw(const bContext *C, wmManipulator *mpr) } } -static void manipulator_dial_modal(bContext *C, wmManipulator *mpr, const wmEvent *event, const int UNUSED(flag)) +static void manipulator_dial_modal( + bContext *C, wmManipulator *mpr, const wmEvent *event, + eWM_ManipulatorTweak UNUSED(tweak_flag)) { const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f}; /* coordinate at which the arc drawing will be started */ float angle_ofs, angle_delta; diff --git a/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c index 6943ae2c9f0..d4b98ec514a 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c @@ -31,6 +31,8 @@ * - `matrix[1]` currently not used. * - `matrix[2]` is the widget direction (for all manipulators). * + * TODO: use matrix_space + * */ #include "BIF_gl.h" @@ -63,7 +65,9 @@ #include "../manipulator_geometry.h" #include "../manipulator_library_intern.h" -static void manipulator_grab_modal(bContext *C, wmManipulator *mpr, const wmEvent *event, const int flag); +static void manipulator_grab_modal( + bContext *C, wmManipulator *mpr, const wmEvent *event, + eWM_ManipulatorTweak tweak_flag); typedef struct GrabInteraction { float init_mval[2]; @@ -139,6 +143,7 @@ static void grab3d_draw_intern( float col[4]; BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D); + UNUSED_VARS_NDEBUG(C); manipulator_color_get(mpr, highlight, col); @@ -168,25 +173,27 @@ static void grab3d_draw_intern( } } -static void manipulator_grab_draw_select(const bContext *C, wmManipulator *mpr, int selectionbase) +static void manipulator_grab_draw_select(const bContext *C, wmManipulator *mpr, int select_id) { - GPU_select_load_id(selectionbase); + GPU_select_load_id(select_id); grab3d_draw_intern(C, mpr, true, false); } static void manipulator_grab_draw(const bContext *C, wmManipulator *mpr) { - const bool active = mpr->state & WM_MANIPULATOR_STATE_ACTIVE; - const bool highlight = (mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT) != 0; + const bool is_modal = mpr->state & WM_MANIPULATOR_STATE_MODAL; + const bool is_highlight = (mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT) != 0; - (void)active; + (void)is_modal; glEnable(GL_BLEND); - grab3d_draw_intern(C, mpr, false, highlight); + grab3d_draw_intern(C, mpr, false, is_highlight); glDisable(GL_BLEND); } -static void manipulator_grab_modal(bContext *C, wmManipulator *mpr, const wmEvent *event, const int UNUSED(flag)) +static void manipulator_grab_modal( + bContext *C, wmManipulator *mpr, const wmEvent *event, + eWM_ManipulatorTweak UNUSED(tweak_flag)) { GrabInteraction *inter = mpr->interaction_data; diff --git a/source/blender/editors/manipulator_library/manipulator_types/primitive3d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/primitive3d_manipulator.c index f6c83a4934c..6a7fde5a5b5 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/primitive3d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/primitive3d_manipulator.c @@ -27,6 +27,8 @@ * * \brief Manipulator with primitive drawing type (plane, cube, etc.). * Currently only plane primitive supported without own handling, use with operator only. + * + * TODO: use matrix_space */ #include "BIF_gl.h" @@ -133,9 +135,9 @@ static void manipulator_primitive_draw_intern( static void manipulator_primitive_draw_select( const bContext *UNUSED(C), wmManipulator *mpr, - int selectionbase) + int select_id) { - GPU_select_load_id(selectionbase); + GPU_select_load_id(select_id); manipulator_primitive_draw_intern(mpr, true, false); } @@ -148,7 +150,7 @@ static void manipulator_primitive_draw(const bContext *UNUSED(C), wmManipulator static void manipulator_primitive_setup(wmManipulator *mpr) { - mpr->flag |= WM_MANIPULATOR_DRAW_ACTIVE; + mpr->flag |= WM_MANIPULATOR_DRAW_MODAL; } static void manipulator_primitive_invoke( diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index cd7940126ec..8aa3b63f795 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -396,7 +396,7 @@ bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], b return true; } -int do_paintface_box_select(ViewContext *vc, rcti *rect, bool select, bool extend) +int do_paintface_box_select(const bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend) { Object *ob = vc->obact; Mesh *me; @@ -427,7 +427,7 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, bool select, bool exten } } - ED_view3d_backbuf_validate(vc); + ED_view3d_backbuf_validate(C, vc); ibuf = IMB_allocImBuf(size[0], size[1], 32, IB_rect); rt = ibuf->rect; @@ -801,25 +801,47 @@ void ED_mesh_mirrtopo_init(Mesh *me, DerivedMesh *dm, const int ob_mode, MirrTop qsort(topo_pairs, totvert, sizeof(MirrTopoVert_t), mirrtopo_vert_sort); - /* Since the loop starts at 2, we must define the last index where the hash's differ */ - last = ((totvert >= 2) && (topo_pairs[0].hash == topo_pairs[1].hash)) ? 0 : 1; + last = 0; /* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2, * but you cant ever access the last 'a' index of MirrTopoPairs */ - for (a = 2; a <= totvert; a++) { - /* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a ].hash, MirrTopoPairs[a ].v_index ); */ - if ((a == totvert) || (topo_pairs[a - 1].hash != topo_pairs[a].hash)) { - if (a - last == 2) { - if (em) { - index_lookup[topo_pairs[a - 1].v_index] = (intptr_t)BM_vert_at_index(em->bm, topo_pairs[a - 2].v_index); - index_lookup[topo_pairs[a - 2].v_index] = (intptr_t)BM_vert_at_index(em->bm, topo_pairs[a - 1].v_index); + if (em) { + BMVert **vtable = em->bm->vtable; + for (a = 1; a <= totvert; a++) { + /* printf("I %d %ld %d\n", (a - last), MirrTopoPairs[a].hash, MirrTopoPairs[a].v_indexs); */ + if ((a == totvert) || (topo_pairs[a - 1].hash != topo_pairs[a].hash)) { + const int match_count = a - last; + if (match_count == 2) { + const int j = topo_pairs[a - 1].v_index, k = topo_pairs[a - 2].v_index; + index_lookup[j] = (intptr_t)vtable[k]; + index_lookup[k] = (intptr_t)vtable[j]; + } + else if (match_count == 1) { + /* Center vertex. */ + const int j = topo_pairs[a - 1].v_index; + index_lookup[j] = (intptr_t)vtable[j]; + } + last = a; + } + } + } + else { + /* same as above, for mesh */ + for (a = 1; a <= totvert; a++) { + if ((a == totvert) || (topo_pairs[a - 1].hash != topo_pairs[a].hash)) { + const int match_count = a - last; + if (match_count == 2) { + const int j = topo_pairs[a - 1].v_index, k = topo_pairs[a - 2].v_index; + index_lookup[j] = k; + index_lookup[k] = j; } - else { - index_lookup[topo_pairs[a - 1].v_index] = topo_pairs[a - 2].v_index; - index_lookup[topo_pairs[a - 2].v_index] = topo_pairs[a - 1].v_index; + else if (match_count == 1) { + /* Center vertex. */ + const int j = topo_pairs[a - 1].v_index; + index_lookup[j] = j; } + last = a; } - last = a; } } diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c index 9b6df11d470..9b97484c8d9 100644 --- a/source/blender/editors/mesh/editmesh_bisect.c +++ b/source/blender/editors/mesh/editmesh_bisect.c @@ -615,9 +615,9 @@ static void manipulator_mesh_bisect_setup(const bContext *C, wmManipulatorGroup const wmManipulatorType *wt_grab = WM_manipulatortype_find("MANIPULATOR_WT_grab_3d", true); const wmManipulatorType *wt_dial = WM_manipulatortype_find("MANIPULATOR_WT_dial_3d", true); - man->translate_z = WM_manipulator_new_ptr(wt_arrow, mgroup, "translate_z", NULL); - man->translate_c = WM_manipulator_new_ptr(wt_grab, mgroup, "translate_c", NULL); - man->rotate_c = WM_manipulator_new_ptr(wt_dial, mgroup, "rotate_c", NULL); + man->translate_z = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); + man->translate_c = WM_manipulator_new_ptr(wt_grab, mgroup, NULL); + man->rotate_c = WM_manipulator_new_ptr(wt_dial, mgroup, NULL); RNA_enum_set(man->translate_z->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_NORMAL); RNA_enum_set(man->translate_c->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_RING); diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index d5b2a3d3b82..e7be66e0276 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -1078,10 +1078,10 @@ static void manipulator_mesh_spin_setup(const bContext *C, wmManipulatorGroup *m const wmManipulatorType *wt_grab = WM_manipulatortype_find("MANIPULATOR_WT_grab_3d", true); const wmManipulatorType *wt_dial = WM_manipulatortype_find("MANIPULATOR_WT_dial_3d", true); - man->translate_z = WM_manipulator_new_ptr(wt_arrow, mgroup, "translate_z", NULL); - man->translate_c = WM_manipulator_new_ptr(wt_grab, mgroup, "translate_c", NULL); - man->rotate_c = WM_manipulator_new_ptr(wt_dial, mgroup, "rotate_c", NULL); - man->angle_z = WM_manipulator_new_ptr(wt_dial, mgroup, "angle_z", NULL); + man->translate_z = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); + man->translate_c = WM_manipulator_new_ptr(wt_grab, mgroup, NULL); + man->rotate_c = WM_manipulator_new_ptr(wt_dial, mgroup, NULL); + man->angle_z = WM_manipulator_new_ptr(wt_dial, mgroup, NULL); RNA_enum_set(man->translate_z->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_NORMAL); RNA_enum_set(man->translate_c->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_RING); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 3c974e4b3b9..37d86ee313f 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -54,6 +54,8 @@ #include "BKE_editmesh_bvh.h" #include "BKE_report.h" +#include "DEG_depsgraph.h" + #include "GPU_immediate.h" #include "GPU_matrix.h" @@ -1812,7 +1814,7 @@ static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], mul_m4_v3(kcd->ob->imat, r_origin_ofs); } -static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float cageco[3], bool *is_space) +static BMFace *knife_find_closest_face(const bContext *C, KnifeTool_OpData *kcd, float co[3], float cageco[3], bool *is_space) { BMFace *f; float dist = KMAXDIST; @@ -1837,7 +1839,7 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float if (!f) { if (kcd->is_interactive) { /* try to use backbuffer selection method if ray casting failed */ - f = EDBM_face_find_nearest(&kcd->vc, &dist); + f = EDBM_face_find_nearest(C, &kcd->vc, &dist); /* cheat for now; just put in the origin instead * of a true coordinate on the face. @@ -1851,7 +1853,7 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float /* find the 2d screen space density of vertices within a radius. used to scale snapping * distance for picking edges/verts.*/ -static int knife_sample_screen_density(KnifeTool_OpData *kcd, const float radius) +static int knife_sample_screen_density(const bContext *C, KnifeTool_OpData *kcd, const float radius) { BMFace *f; bool is_space; @@ -1859,7 +1861,7 @@ static int knife_sample_screen_density(KnifeTool_OpData *kcd, const float radius BLI_assert(kcd->is_interactive == true); - f = knife_find_closest_face(kcd, co, cageco, &is_space); + f = knife_find_closest_face(C, kcd, co, cageco, &is_space); if (f && !is_space) { const float radius_sq = radius * radius; @@ -1902,15 +1904,15 @@ static int knife_sample_screen_density(KnifeTool_OpData *kcd, const float radius /* returns snapping distance for edges/verts, scaled by the density of the * surrounding mesh (in screen space)*/ -static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize) +static float knife_snap_size(const bContext *C, KnifeTool_OpData *kcd, float maxsize) { - float density = (float)knife_sample_screen_density(kcd, maxsize * 2.0f); + float density = (float)knife_sample_screen_density(C, kcd, maxsize * 2.0f); return min_ff(maxsize / (density * 0.5f), maxsize); } /* p is closest point on edge to the mouse cursor */ -static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], float cagep[3], +static KnifeEdge *knife_find_closest_edge(const bContext *C, KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr, bool *is_space) { BMFace *f; @@ -1918,7 +1920,7 @@ static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], flo float maxdist; if (kcd->is_interactive) { - maxdist = knife_snap_size(kcd, kcd->ethresh); + maxdist = knife_snap_size(C, kcd, kcd->ethresh); if (kcd->ignore_vert_snapping) { maxdist *= 0.5f; @@ -1928,7 +1930,7 @@ static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], flo maxdist = KNIFE_FLT_EPS; } - f = knife_find_closest_face(kcd, co, cageco, NULL); + f = knife_find_closest_face(C, kcd, co, cageco, NULL); *is_space = !f; kcd->curr.bmface = f; @@ -2042,7 +2044,7 @@ static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], flo } /* find a vertex near the mouse cursor, if it exists */ -static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr, +static KnifeVert *knife_find_closest_vert(const bContext *C, KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr, bool *is_space) { BMFace *f; @@ -2050,7 +2052,7 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo float maxdist; if (kcd->is_interactive) { - maxdist = knife_snap_size(kcd, kcd->vthresh); + maxdist = knife_snap_size(C, kcd, kcd->vthresh); if (kcd->ignore_vert_snapping) { maxdist *= 0.5f; } @@ -2059,7 +2061,7 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo maxdist = KNIFE_FLT_EPS; } - f = knife_find_closest_face(kcd, co, cageco, is_space); + f = knife_find_closest_face(C, kcd, co, cageco, is_space); kcd->curr.bmface = f; @@ -2181,7 +2183,7 @@ static bool knife_snap_angle(KnifeTool_OpData *kcd) } /* update active knife edge/vert pointers */ -static int knife_update_active(KnifeTool_OpData *kcd) +static int knife_update_active(const bContext *C, KnifeTool_OpData *kcd) { knife_pos_data_clear(&kcd->curr); copy_v2_v2(kcd->curr.mval, kcd->mval); @@ -2196,13 +2198,13 @@ static int knife_update_active(KnifeTool_OpData *kcd) kcd->is_angle_snapping = false; } - kcd->curr.vert = knife_find_closest_vert(kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.bmface, &kcd->curr.is_space); + kcd->curr.vert = knife_find_closest_vert(C, kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.bmface, &kcd->curr.is_space); if (!kcd->curr.vert && /* no edge snapping while dragging (edges are too sticky when cuts are immediate) */ !kcd->is_drag_hold) { - kcd->curr.edge = knife_find_closest_edge(kcd, kcd->curr.co, kcd->curr.cage, + kcd->curr.edge = knife_find_closest_edge(C, kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.bmface, &kcd->curr.is_space); } @@ -2569,27 +2571,30 @@ static void knifetool_exit(bContext *C, wmOperator *op) op->customdata = NULL; } -static void knifetool_update_mval(KnifeTool_OpData *kcd, const float mval[2]) +static void knifetool_update_mval(const bContext *C, KnifeTool_OpData *kcd, const float mval[2]) { knife_recalc_projmat(kcd); copy_v2_v2(kcd->mval, mval); - if (knife_update_active(kcd)) { + if (knife_update_active(C, kcd)) { ED_region_tag_redraw(kcd->ar); } } -static void knifetool_update_mval_i(KnifeTool_OpData *kcd, const int mval_i[2]) +static void knifetool_update_mval_i(const bContext *C, KnifeTool_OpData *kcd, const int mval_i[2]) { float mval[2] = {UNPACK2(mval_i)}; - knifetool_update_mval(kcd, mval); + knifetool_update_mval(C, kcd, mval); } -static void knifetool_init_bmbvh(KnifeTool_OpData *kcd) +static void knifetool_init_bmbvh(const bContext *C, KnifeTool_OpData *kcd) { + EvaluationContext eval_ctx; BM_mesh_elem_index_ensure(kcd->em->bm, BM_VERT); - kcd->cagecos = (const float (*)[3])BKE_editmesh_vertexCos_get(kcd->em, kcd->scene, NULL); + CTX_data_eval_ctx(C, &eval_ctx); + + kcd->cagecos = (const float (*)[3])BKE_editmesh_vertexCos_get(&eval_ctx, kcd->em, kcd->scene, NULL); kcd->bmbvh = BKE_bmbvh_new_from_editmesh( kcd->em, @@ -2632,7 +2637,7 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd, kcd->cut_through = cut_through; kcd->only_select = only_select; - knifetool_init_bmbvh(kcd); + knifetool_init_bmbvh(C, kcd); kcd->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 15), "knife"); #ifdef USE_NET_ISLAND_CONNECT @@ -2704,7 +2709,7 @@ static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event) WM_cursor_modal_set(CTX_wm_window(C), BC_KNIFECURSOR); WM_event_add_modal_handler(C, op); - knifetool_update_mval_i(kcd, event->mval); + knifetool_update_mval_i(C, kcd, event->mval); knife_update_header(C, op, kcd); @@ -2810,7 +2815,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event) kcd->snap_midpoints = true; knife_recalc_projmat(kcd); - knife_update_active(kcd); + knife_update_active(C, kcd); knife_update_header(C, op, kcd); ED_region_tag_redraw(kcd->ar); do_refresh = true; @@ -2819,7 +2824,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event) kcd->snap_midpoints = false; knife_recalc_projmat(kcd); - knife_update_active(kcd); + knife_update_active(C, kcd); knife_update_header(C, op, kcd); ED_region_tag_redraw(kcd->ar); do_refresh = true; @@ -2874,7 +2879,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event) kcd->is_drag_hold = false; /* needed because the last face 'hit' is ignored when dragging */ - knifetool_update_mval(kcd, kcd->curr.mval); + knifetool_update_mval(C, kcd, kcd->curr.mval); } ED_region_tag_redraw(kcd->ar); @@ -2885,14 +2890,14 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event) /* shouldn't be possible with default key-layout, just incase... */ if (kcd->is_drag_hold) { kcd->is_drag_hold = false; - knifetool_update_mval(kcd, kcd->curr.mval); + knifetool_update_mval(C, kcd, kcd->curr.mval); } kcd->prev = kcd->curr; kcd->curr = kcd->init; knife_project_v2(kcd, kcd->curr.cage, kcd->curr.mval); - knifetool_update_mval(kcd, kcd->curr.mval); + knifetool_update_mval(C, kcd, kcd->curr.mval); knife_add_cut(kcd); @@ -2926,7 +2931,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_PASS_THROUGH; case MOUSEMOVE: /* mouse moved somewhere to select another loop */ if (kcd->mode != MODE_PANNING) { - knifetool_update_mval_i(kcd, event->mval); + knifetool_update_mval_i(C, kcd, event->mval); if (kcd->is_drag_hold) { if (kcd->totlinehit >= 2) { @@ -2949,7 +2954,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event) if (do_refresh) { /* we don't really need to update mval, * but this happens to be the best way to refresh at the moment */ - knifetool_update_mval_i(kcd, event->mval); + knifetool_update_mval_i(C, kcd, event->mval); } /* keep going until the user confirms */ @@ -3037,7 +3042,7 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug int i; for (i = 0; i < mval_tot; i++) { - knifetool_update_mval(kcd, mval_fl[i]); + knifetool_update_mval(C, kcd, mval_fl[i]); if (i == 0) { knife_start_cut(kcd); kcd->mode = MODE_DRAGGING; @@ -3068,7 +3073,7 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug /* freed on knifetool_finish_ex, but we need again to check if points are visible */ if (kcd->cut_through == false) { - knifetool_init_bmbvh(kcd); + knifetool_init_bmbvh(C, kcd); } ED_view3d_ob_project_mat_get(kcd->ar->regiondata, kcd->ob, projmat); diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c index 0d3cc07589b..c98d22503e1 100644 --- a/source/blender/editors/mesh/editmesh_knife_project.c +++ b/source/blender/editors/mesh/editmesh_knife_project.c @@ -42,6 +42,8 @@ #include "BKE_editmesh.h" #include "BKE_report.h" +#include "DEG_depsgraph.h" + #include "RNA_define.h" #include "RNA_access.h" @@ -56,13 +58,17 @@ #include "mesh_intern.h" /* own include */ -static LinkNode *knifeproject_poly_from_object(ARegion *ar, Scene *scene, Object *ob, LinkNode *polys) +static LinkNode *knifeproject_poly_from_object(const bContext *C, Scene *scene, Object *ob, LinkNode *polys) { + ARegion *ar = CTX_wm_region(C); + EvaluationContext eval_ctx; DerivedMesh *dm; bool dm_needsFree; + CTX_data_eval_ctx(C, &eval_ctx); + if (ob->type == OB_MESH || ob->derivedFinal) { - dm = ob->derivedFinal ? ob->derivedFinal : mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + dm = ob->derivedFinal ? ob->derivedFinal : mesh_get_derived_final(&eval_ctx, scene, ob, CD_MASK_BAREMESH); dm_needsFree = false; } else if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { @@ -116,7 +122,6 @@ static LinkNode *knifeproject_poly_from_object(ARegion *ar, Scene *scene, Object static int knifeproject_exec(bContext *C, wmOperator *op) { - ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); @@ -127,7 +132,7 @@ static int knifeproject_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { if (ob != obedit) { - polys = knifeproject_poly_from_object(ar, scene, ob, polys); + polys = knifeproject_poly_from_object(C, scene, ob, polys); } } CTX_DATA_END; diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 6a656ace09c..8db3a2c8d04 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -556,10 +556,10 @@ static void loopcut_update_edge(RingSelOpData *lcd, BMEdge *e, const int preview } } -static void loopcut_mouse_move(RingSelOpData *lcd, const int previewlines) +static void loopcut_mouse_move(const bContext *C, RingSelOpData *lcd, const int previewlines) { float dist = ED_view3d_select_dist_px(); - BMEdge *e = EDBM_edge_find_nearest(&lcd->vc, &dist); + BMEdge *e = EDBM_edge_find_nearest(C, &lcd->vc, &dist); loopcut_update_edge(lcd, e, previewlines); } @@ -597,7 +597,7 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event) if (is_interactive) { copy_v2_v2_int(lcd->vc.mval, event->mval); - loopcut_mouse_move(lcd, is_interactive ? 1 : 0); + loopcut_mouse_move(C, lcd, is_interactive ? 1 : 0); } else { const int e_index = RNA_int_get(op->ptr, "edge_index"); @@ -761,7 +761,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event) if (!has_numinput) { lcd->vc.mval[0] = event->mval[0]; lcd->vc.mval[1] = event->mval[1]; - loopcut_mouse_move(lcd, (int)lcd->cuts); + loopcut_mouse_move(C, lcd, (int)lcd->cuts); ED_region_tag_redraw(lcd->ar); handled = true; diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c index 4431712e720..0a36b735f39 100644 --- a/source/blender/editors/mesh/editmesh_path.c +++ b/source/blender/editors/mesh/editmesh_path.c @@ -570,19 +570,19 @@ static bool edbm_shortest_path_pick_ex( static int edbm_shortest_path_pick_exec(bContext *C, wmOperator *op); -static BMElem *edbm_elem_find_nearest(ViewContext *vc, const char htype) +static BMElem *edbm_elem_find_nearest(const bContext *C, ViewContext *vc, const char htype) { BMEditMesh *em = vc->em; float dist = ED_view3d_select_dist_px(); if ((em->selectmode & SCE_SELECT_VERTEX) && (htype == BM_VERT)) { - return (BMElem *)EDBM_vert_find_nearest(vc, &dist); + return (BMElem *)EDBM_vert_find_nearest(C, vc, &dist); } else if ((em->selectmode & SCE_SELECT_EDGE) && (htype == BM_EDGE)) { - return (BMElem *)EDBM_edge_find_nearest(vc, &dist); + return (BMElem *)EDBM_edge_find_nearest(C, vc, &dist); } else if ((em->selectmode & SCE_SELECT_FACE) && (htype == BM_FACE)) { - return (BMElem *)EDBM_face_find_nearest(vc, &dist); + return (BMElem *)EDBM_face_find_nearest(C, vc, &dist); } return NULL; @@ -617,14 +617,14 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE BMElem *ele_src, *ele_dst; if (!(ele_src = edbm_elem_active_elem_or_face_get(em->bm)) || - !(ele_dst = edbm_elem_find_nearest(&vc, ele_src->head.htype))) + !(ele_dst = edbm_elem_find_nearest(C, &vc, ele_src->head.htype))) { /* special case, toggle edge tags even when we don't have a path */ if (((em->selectmode & SCE_SELECT_EDGE) && (vc.scene->toolsettings->edge_mode != EDGE_MODE_SELECT)) && /* check if we only have a destination edge */ ((ele_src == NULL) && - (ele_dst = edbm_elem_find_nearest(&vc, BM_EDGE)))) + (ele_dst = edbm_elem_find_nearest(C, &vc, BM_EDGE)))) { ele_src = ele_dst; track_active = false; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index c8d8ac68334..97ae8ae166d 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -194,7 +194,7 @@ static BLI_bitmap *edbm_backbuf_alloc(const int size) /* reads rect, and builds selection array for quick lookup */ /* returns if all is OK */ -bool EDBM_backbuf_border_init(ViewContext *vc, short xmin, short ymin, short xmax, short ymax) +bool EDBM_backbuf_border_init(const bContext *C, ViewContext *vc, short xmin, short ymin, short xmax, short ymax) { struct ImBuf *buf; unsigned int *dr; @@ -204,7 +204,7 @@ bool EDBM_backbuf_border_init(ViewContext *vc, short xmin, short ymin, short xma return false; } - buf = ED_view3d_backbuf_read(vc, xmin, ymin, xmax, ymax); + buf = ED_view3d_backbuf_read(C, vc, xmin, ymin, xmax, ymax); if ((buf == NULL) || (bm_vertoffs == 0)) { return false; } @@ -267,7 +267,7 @@ static void edbm_mask_lasso_px_cb(int x, int x_end, int y, void *user_data) * - grab again and compare * returns 'OK' */ -bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) +bool EDBM_backbuf_border_mask_init(const bContext *C, ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) { unsigned int *dr, *dr_mask, *dr_mask_arr; struct ImBuf *buf; @@ -284,7 +284,7 @@ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short return false; } - buf = ED_view3d_backbuf_read(vc, xmin, ymin, xmax, ymax); + buf = ED_view3d_backbuf_read(C, vc, xmin, ymin, xmax, ymax); if ((buf == NULL) || (bm_vertoffs == 0)) { return false; } @@ -317,7 +317,7 @@ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short } /* circle shaped sample area */ -bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads) +bool EDBM_backbuf_circle_init(const bContext *C, ViewContext *vc, short xs, short ys, short rads) { struct ImBuf *buf; unsigned int *dr; @@ -336,7 +336,7 @@ bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads) xmin = xs - rads; xmax = xs + rads; ymin = ys - rads; ymax = ys + rads; - buf = ED_view3d_backbuf_read(vc, xmin, ymin, xmax, ymax); + buf = ED_view3d_backbuf_read(C, vc, xmin, ymin, xmax, ymax); if ((buf == NULL) || (bm_vertoffs == 0)) { return false; } @@ -435,7 +435,7 @@ static void findnearestvert__doClosest(void *userData, BMVert *eve, const float * \param use_cycle Cycle over elements within #FIND_NEAR_CYCLE_THRESHOLD_MIN in order of index. */ BMVert *EDBM_vert_find_nearest_ex( - ViewContext *vc, float *r_dist, + const bContext *C, ViewContext *vc, float *r_dist, const bool use_select_bias, bool use_cycle) { BMesh *bm = vc->em->bm; @@ -447,10 +447,10 @@ BMVert *EDBM_vert_find_nearest_ex( BMVert *eve; /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */ - ED_view3d_backbuf_validate(vc); + ED_view3d_backbuf_validate(C, vc); index = ED_view3d_backbuf_sample_rect( - vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &dist_test); + C, vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &dist_test); eve = index ? BM_vert_at_index_find_or_table(bm, index - 1) : NULL; if (eve) { @@ -485,7 +485,7 @@ BMVert *EDBM_vert_find_nearest_ex( data.cycle_index_prev = prev_select_index; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, clip_flag); + mesh_foreachScreenVert(C, vc, findnearestvert__doClosest, &data, clip_flag); hit = (data.use_cycle && data.hit_cycle.vert) ? &data.hit_cycle : &data.hit; *r_dist = hit->dist; @@ -497,9 +497,9 @@ BMVert *EDBM_vert_find_nearest_ex( } } -BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist) +BMVert *EDBM_vert_find_nearest(const bContext *C, ViewContext *vc, float *r_dist) { - return EDBM_vert_find_nearest_ex(vc, r_dist, false, false); + return EDBM_vert_find_nearest_ex(C, vc, r_dist, false, false); } /* find the distance to the edge we already have */ @@ -621,7 +621,7 @@ static void find_nearest_edge__doClosest( } BMEdge *EDBM_edge_find_nearest_ex( - ViewContext *vc, float *r_dist, + const bContext *C, ViewContext *vc, float *r_dist, float *r_dist_center, const bool use_select_bias, const bool use_cycle, BMEdge **r_eed_zbuf) @@ -635,9 +635,9 @@ BMEdge *EDBM_edge_find_nearest_ex( BMEdge *eed; /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */ - ED_view3d_backbuf_validate(vc); + ED_view3d_backbuf_validate(C, vc); - index = ED_view3d_backbuf_sample_rect(vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &dist_test); + index = ED_view3d_backbuf_sample_rect(C, vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &dist_test); eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : NULL; if (r_eed_zbuf) { @@ -655,7 +655,7 @@ BMEdge *EDBM_edge_find_nearest_ex( ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenEdge(vc, find_nearest_edge_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenEdge(C, vc, find_nearest_edge_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT); *r_dist_center = data.dist; } @@ -695,7 +695,7 @@ BMEdge *EDBM_edge_find_nearest_ex( data.cycle_index_prev = prev_select_index; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenEdge(vc, find_nearest_edge__doClosest, &data, clip_flag); + mesh_foreachScreenEdge(C, vc, find_nearest_edge__doClosest, &data, clip_flag); hit = (data.use_cycle && data.hit_cycle.edge) ? &data.hit_cycle : &data.hit; *r_dist = hit->dist; @@ -711,9 +711,9 @@ BMEdge *EDBM_edge_find_nearest_ex( } BMEdge *EDBM_edge_find_nearest( - ViewContext *vc, float *r_dist) + const bContext *C, ViewContext *vc, float *r_dist) { - return EDBM_edge_find_nearest_ex(vc, r_dist, NULL, false, false, NULL); + return EDBM_edge_find_nearest_ex(C, vc, r_dist, NULL, false, false, NULL); } /* find the distance to the face we already have */ @@ -787,7 +787,7 @@ static void findnearestface__doClosest(void *userData, BMFace *efa, const float BMFace *EDBM_face_find_nearest_ex( - ViewContext *vc, float *r_dist, + const bContext *C, ViewContext *vc, float *r_dist, float *r_dist_center, const bool use_select_bias, const bool use_cycle, BMFace **r_efa_zbuf) @@ -799,9 +799,9 @@ BMFace *EDBM_face_find_nearest_ex( unsigned int index; BMFace *efa; - ED_view3d_backbuf_validate(vc); + ED_view3d_backbuf_validate(C, vc); - index = ED_view3d_backbuf_sample(vc, vc->mval[0], vc->mval[1]); + index = ED_view3d_backbuf_sample(C, vc, vc->mval[0], vc->mval[1]); efa = index ? BM_face_at_index_find_or_table(bm, index - 1) : NULL; if (r_efa_zbuf) { @@ -819,7 +819,7 @@ BMFace *EDBM_face_find_nearest_ex( ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenFace(vc, find_nearest_face_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenFace(C, vc, find_nearest_face_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT); *r_dist_center = data.dist; } @@ -857,7 +857,7 @@ BMFace *EDBM_face_find_nearest_ex( data.cycle_index_prev = prev_select_index; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, clip_flag); + mesh_foreachScreenFace(C, vc, findnearestface__doClosest, &data, clip_flag); hit = (data.use_cycle && data.hit_cycle.face) ? &data.hit_cycle : &data.hit; *r_dist = hit->dist; @@ -872,9 +872,9 @@ BMFace *EDBM_face_find_nearest_ex( } } -BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) +BMFace *EDBM_face_find_nearest(const bContext *C, ViewContext *vc, float *r_dist) { - return EDBM_face_find_nearest_ex(vc, r_dist, NULL, false, false, NULL); + return EDBM_face_find_nearest_ex(C, vc, r_dist, NULL, false, false, NULL); } #undef FIND_NEAR_SELECT_BIAS @@ -886,7 +886,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) * selected vertices and edges get disadvantage * return 1 if found one */ -static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa) +static int unified_findnearest(const bContext *C, ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa) { BMEditMesh *em = vc->em; static short mval_prev[2] = {-1, -1}; @@ -905,12 +905,12 @@ static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, /* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */ - ED_view3d_backbuf_validate(vc); + ED_view3d_backbuf_validate(C, vc); if ((dist > 0.0f) && em->selectmode & SCE_SELECT_FACE) { float dist_center = 0.0f; float *dist_center_p = (em->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_VERTEX)) ? &dist_center : NULL; - efa = EDBM_face_find_nearest_ex(vc, &dist, dist_center_p, true, use_cycle, &efa_zbuf); + efa = EDBM_face_find_nearest_ex(C, vc, &dist, dist_center_p, true, use_cycle, &efa_zbuf); if (efa && dist_center_p) { dist = min_ff(dist_margin, dist_center); } @@ -919,14 +919,14 @@ static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, if ((dist > 0.0f) && (em->selectmode & SCE_SELECT_EDGE)) { float dist_center = 0.0f; float *dist_center_p = (em->selectmode & SCE_SELECT_VERTEX) ? &dist_center : NULL; - eed = EDBM_edge_find_nearest_ex(vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf); + eed = EDBM_edge_find_nearest_ex(C, vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf); if (eed && dist_center_p) { dist = min_ff(dist_margin, dist_center); } } if ((dist > 0.0f) && em->selectmode & SCE_SELECT_VERTEX) { - eve = EDBM_vert_find_nearest_ex(vc, &dist, true, use_cycle); + eve = EDBM_vert_find_nearest_ex(C, vc, &dist, true, use_cycle); } /* return only one of 3 pointers, for frontbuffer redraws */ @@ -1574,9 +1574,9 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de em = vc.em; /* no afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad */ - ED_view3d_backbuf_validate(&vc); + ED_view3d_backbuf_validate(C, &vc); - eed = EDBM_edge_find_nearest_ex(&vc, &dist, NULL, true, true, NULL); + eed = EDBM_edge_find_nearest_ex(C, &vc, &dist, NULL, true, true, NULL); if (eed == NULL) { return false; } @@ -1829,7 +1829,7 @@ bool EDBM_select_pick(bContext *C, const int mval[2], bool extend, bool deselect vc.mval[0] = mval[0]; vc.mval[1] = mval[1]; - if (unified_findnearest(&vc, &eve, &eed, &efa)) { + if (unified_findnearest(C, &vc, &eve, &eed, &efa)) { /* Deselect everything */ if (extend == false && deselect == false && toggle == false) @@ -1916,12 +1916,30 @@ bool EDBM_select_pick(bContext *C, const int mval[2], bool extend, bool deselect EDBM_selectmode_flush(vc.em); - /* change active material on object */ - if (efa && efa->mat_nr != vc.obedit->actcol - 1) { - vc.obedit->actcol = efa->mat_nr + 1; - vc.em->mat_nr = efa->mat_nr; + if (efa) { + /* Change active material on object. */ + if (efa->mat_nr != vc.obedit->actcol - 1) { + vc.obedit->actcol = efa->mat_nr + 1; + vc.em->mat_nr = efa->mat_nr; + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL); + } - WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL); + /* Change active face-map on object. */ + if (!BLI_listbase_is_empty(&vc.obedit->fmaps)) { + const int cd_fmap_offset = CustomData_get_offset(&vc.em->bm->pdata, CD_FACEMAP); + if (cd_fmap_offset != -1) { + int map = *((int *)BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset)); + if ((map < -1) || (map > BLI_listbase_count_ex(&vc.obedit->fmaps, map))) { + map = -1; + } + map += 1; + if (map != vc.obedit->actfmap) { + /* We may want to add notifiers later, + * currently select update handles redraw. */ + vc.obedit->actfmap = map; + } + } + } } @@ -2804,7 +2822,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE vc.mval[1] = event->mval[1]; /* return warning! */ - if (unified_findnearest(&vc, &eve, &eed, &efa) == 0) { + if (unified_findnearest(C, &vc, &eve, &eed, &efa) == 0) { WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); return OPERATOR_CANCELLED; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index cbed6a37c1f..023b05db62f 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -317,7 +317,7 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) float mval[2], co_proj[3]; if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { if (ED_transform_snap_object_project_view3d_mixed( - snap_context, + C, snap_context, SCE_SELECT_FACE, &(const struct SnapObjectParams){ .snap_select = SNAP_NOT_ACTIVE, diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c index 66c77593c75..e5705d2d3e7 100644 --- a/source/blender/editors/mesh/mesh_navmesh.c +++ b/source/blender/editors/mesh/mesh_navmesh.c @@ -73,18 +73,21 @@ static void createVertsTrisData(bContext *C, LinkNode *obs, LinkNode *oblink, *dmlink; DerivedMesh *dm; Scene *scene = CTX_data_scene(C); + EvaluationContext eval_ctx; LinkNode *dms = NULL; int nverts, ntris, *tris; float *verts; + CTX_data_eval_ctx(C, &eval_ctx); + nverts = 0; ntris = 0; /* calculate number of verts and tris */ for (oblink = obs; oblink; oblink = oblink->next) { ob = (Object *) oblink->link; - dm = mesh_create_derived_no_virtual(scene, ob, NULL, CD_MASK_MESH); + dm = mesh_create_derived_no_virtual(&eval_ctx, scene, ob, NULL, CD_MASK_MESH); DM_ensure_tessface(dm); BLI_linklist_prepend(&dms, dm); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index e7b1f925d5e..7ec8e42e6df 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -79,7 +79,7 @@ * return 0 if no join is made (error) and 1 if the join is done */ static void join_mesh_single( - Main *bmain, Scene *scene, + bContext *C, Main *bmain, Scene *scene, Object *ob_dst, Base *base_src, float imat[4][4], MVert **mvert_pp, MEdge **medge_pp, MLoop **mloop_pp, MPoly **mpoly_pp, CustomData *vdata, CustomData *edata, CustomData *ldata, CustomData *pdata, @@ -95,6 +95,9 @@ static void join_mesh_single( MEdge *medge = *medge_pp; MLoop *mloop = *mloop_pp; MPoly *mpoly = *mpoly_pp; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); if (me->totvert) { /* merge customdata flag */ @@ -216,7 +219,7 @@ static void join_mesh_single( if (base_src->object != ob_dst) { MultiresModifierData *mmd; - multiresModifier_prepare_join(scene, base_src->object, ob_dst); + multiresModifier_prepare_join(&eval_ctx, scene, base_src->object, ob_dst); if ((mmd = get_multires_modifier(scene, base_src->object, true))) { ED_object_iter_other(bmain, base_src->object, true, @@ -505,7 +508,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) * active mesh will remain first ones in new result of the merge, in same order for CD layers, etc. See also T50084. */ join_mesh_single( - bmain, scene, + C, bmain, scene, ob, ob_base, imat, &mvert, &medge, &mloop, &mpoly, &vdata, &edata, &ldata, &pdata, @@ -522,7 +525,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) /* only join if this is a mesh */ if (base->object->type == OB_MESH) { join_mesh_single( - bmain, scene, + C, bmain, scene, ob, base, imat, &mvert, &medge, &mloop, &mpoly, &vdata, &edata, &ldata, &pdata, @@ -624,6 +627,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + EvaluationContext eval_ctx; Mesh *me = (Mesh *)ob->data; Mesh *selme = NULL; DerivedMesh *dm = NULL; @@ -631,6 +635,8 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op) KeyBlock *kb; bool ok = false, nonequal_verts = false; + CTX_data_eval_ctx(C, &eval_ctx); + CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { if (base->object == ob) continue; @@ -672,7 +678,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op) selme = (Mesh *)base->object->data; if (selme->totvert == me->totvert) { - dm = mesh_get_derived_deform(scene, base->object, CD_MASK_BAREMESH); + dm = mesh_get_derived_deform(&eval_ctx, scene, base->object, CD_MASK_BAREMESH); if (!dm) continue; @@ -1115,11 +1121,11 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int * on an edge in the backbuf, we can still select a face */ float dummy_dist; - *index = ED_view3d_backbuf_sample_rect(&vc, mval, size, 1, me->totpoly + 1, &dummy_dist); + *index = ED_view3d_backbuf_sample_rect(C, &vc, mval, size, 1, me->totpoly + 1, &dummy_dist); } else { /* sample only on the exact position */ - *index = ED_view3d_backbuf_sample(&vc, mval[0], mval[1]); + *index = ED_view3d_backbuf_sample(C, &vc, mval[0], mval[1]); } if ((*index) == 0 || (*index) > (unsigned int)me->totpoly) @@ -1158,9 +1164,12 @@ static void ed_mesh_pick_face_vert__mpoly_find( */ bool ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size) { + EvaluationContext eval_ctx; unsigned int poly_index; Mesh *me = ob->data; + CTX_data_eval_ctx(C, &eval_ctx); + BLI_assert(me && GS(me->id.name) == ID_ME); if (ED_mesh_pick_face(C, ob, mval, &poly_index, size)) { @@ -1168,7 +1177,7 @@ bool ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned struct ARegion *ar = CTX_wm_region(C); /* derived mesh to find deformed locations */ - DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); + DerivedMesh *dm = mesh_get_derived_final(&eval_ctx, scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); int v_idx_best = ORIGINDEX_NONE; @@ -1265,9 +1274,12 @@ static void ed_mesh_pick_vert__mapFunc(void *userData, int index, const float co } bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size, bool use_zbuf) { + EvaluationContext eval_ctx; ViewContext vc; Mesh *me = ob->data; + CTX_data_eval_ctx(C, &eval_ctx); + BLI_assert(me && GS(me->id.name) == ID_ME); if (!me || me->totvert == 0) @@ -1281,11 +1293,11 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int * on an face in the backbuf, we can still select a vert */ float dummy_dist; - *index = ED_view3d_backbuf_sample_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist); + *index = ED_view3d_backbuf_sample_rect(C, &vc, mval, size, 1, me->totvert + 1, &dummy_dist); } else { /* sample only on the exact position */ - *index = ED_view3d_backbuf_sample(&vc, mval[0], mval[1]); + *index = ED_view3d_backbuf_sample(C, &vc, mval[0], mval[1]); } if ((*index) == 0 || (*index) > (unsigned int)me->totvert) @@ -1295,7 +1307,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int } else { /* derived mesh to find deformed locations */ - DerivedMesh *dm = mesh_get_derived_final(vc.scene, ob, CD_MASK_BAREMESH); + DerivedMesh *dm = mesh_get_derived_final(&eval_ctx, vc.scene, ob, CD_MASK_BAREMESH); ARegion *ar = vc.ar; RegionView3D *rv3d = ar->regiondata; diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index 174057d1fb9..4a7e08c522e 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -595,7 +595,7 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese BLI_rcti_init_pt_radius(&rect, mval, 12); - hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST); + hits = view3d_opengl_select(C, &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST); /* does startelem exist? */ ml = mb->editelems->first; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 491dddb066a..a7cc8e44443 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -224,16 +224,19 @@ void ED_object_base_init_transform(bContext *C, Base *base, const float loc[3], { Object *ob = base->object; Scene *scene = CTX_data_scene(C); + EvaluationContext eval_ctx; if (!scene) return; + CTX_data_eval_ctx(C, &eval_ctx); + if (loc) copy_v3_v3(ob->loc, loc); if (rot) copy_v3_v3(ob->rot, rot); - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); } /* Uses context to figure out transform for primitive. @@ -1639,14 +1642,14 @@ static EnumPropertyItem convert_target_items[] = { {0, NULL, 0, NULL, NULL} }; -static void convert_ensure_curve_cache(Main *bmain, Scene *scene, Object *ob) +static void convert_ensure_curve_cache(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Object *ob) { if (ob->curve_cache == NULL) { /* Force creation. This is normally not needed but on operator * redo we might end up with an object which isn't evaluated yet. */ if (ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) { - BKE_displist_make_curveTypes(scene, ob, false); + BKE_displist_make_curveTypes(eval_ctx, scene, ob, false); } else if (ob->type == OB_MBALL) { BKE_displist_make_mball(bmain->eval_ctx, scene, ob); @@ -1654,9 +1657,9 @@ static void convert_ensure_curve_cache(Main *bmain, Scene *scene, Object *ob) } } -static void curvetomesh(Main *bmain, Scene *scene, Object *ob) +static void curvetomesh(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Object *ob) { - convert_ensure_curve_cache(bmain, scene, ob); + convert_ensure_curve_cache(eval_ctx, bmain, scene, ob); BKE_mesh_from_nurbs(ob); /* also does users */ if (ob->type == OB_MESH) { @@ -1702,6 +1705,7 @@ static int convert_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); SceneLayer *sl = CTX_data_scene_layer(C); + EvaluationContext eval_ctx; Base *basen = NULL, *basact = NULL; Object *ob, *ob1, *newob, *obact = CTX_data_active_object(C); DerivedMesh *dm; @@ -1713,6 +1717,8 @@ static int convert_exec(bContext *C, wmOperator *op) bool keep_original = RNA_boolean_get(op->ptr, "keep_original"); int a, mballConverted = 0; + CTX_data_eval_ctx(C, &eval_ctx); + /* don't forget multiple users! */ { @@ -1755,7 +1761,7 @@ static int convert_exec(bContext *C, wmOperator *op) * However, changing this is more design than bugfix, not to mention convoluted code below, * so that will be for later. * But at the very least, do not do that with linked IDs! */ - if ((ID_IS_LINKED_DATABLOCK(ob) || ID_IS_LINKED_DATABLOCK(ob->data)) && !keep_original) { + if ((ID_IS_LINKED_DATABLOCK(ob) || (ob->data && ID_IS_LINKED_DATABLOCK(ob->data))) && !keep_original) { keep_original = true; BKE_reportf(op->reports, RPT_INFO, "Converting some linked object/object data, enforcing 'Keep Original' option to True"); @@ -1807,7 +1813,7 @@ static int convert_exec(bContext *C, wmOperator *op) newob = ob; } - BKE_mesh_to_curve(scene, newob); + BKE_mesh_to_curve(&eval_ctx, scene, newob); if (newob->type == OB_CURVE) { BKE_object_free_modifiers(newob); /* after derivedmesh calls! */ @@ -1837,7 +1843,7 @@ static int convert_exec(bContext *C, wmOperator *op) /* note: get the mesh from the original, not from the copy in some * cases this doesnt give correct results (when MDEF is used for eg) */ - dm = mesh_get_derived_final(scene, newob, CD_MASK_MESH); + dm = mesh_get_derived_final(&eval_ctx, scene, newob, CD_MASK_MESH); DM_to_mesh(dm, newob->data, newob, CD_MASK_MESH, true); @@ -1909,7 +1915,7 @@ static int convert_exec(bContext *C, wmOperator *op) BKE_curve_curve_dimension_update(cu); if (target == OB_MESH) { - curvetomesh(bmain, scene, newob); + curvetomesh(&eval_ctx, bmain, scene, newob); /* meshes doesn't use displist */ BKE_object_free_curve_cache(newob); @@ -1933,7 +1939,7 @@ static int convert_exec(bContext *C, wmOperator *op) newob = ob; } - curvetomesh(bmain, scene, newob); + curvetomesh(&eval_ctx, bmain, scene, newob); /* meshes doesn't use displist */ BKE_object_free_curve_cache(newob); @@ -1971,7 +1977,7 @@ static int convert_exec(bContext *C, wmOperator *op) for (a = 0; a < newob->totcol; a++) id_us_plus((ID *)me->mat[a]); } - convert_ensure_curve_cache(bmain, scene, baseob); + convert_ensure_curve_cache(&eval_ctx, bmain, scene, baseob); BKE_mesh_from_metaball(&baseob->curve_cache->disp, newob->data); if (obact->type == OB_MBALL) { diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 990761e233a..47dea64bdf7 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -621,12 +621,12 @@ static size_t initialize_internal_images(BakeImages *bake_images, ReportList *re } /* create new mesh with edit mode changes and modifiers applied */ -static Mesh *bake_mesh_new_from_object(Main *bmain, Scene *scene, Object *ob) +static Mesh *bake_mesh_new_from_object(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Object *ob) { if (ob->mode & OB_MODE_EDIT) ED_object_editmode_load(ob); - Mesh *me = BKE_mesh_new_from_object(bmain, scene, ob, 1, 2, 0, 0); + Mesh *me = BKE_mesh_new_from_object(eval_ctx, bmain, scene, ob, 1, 2, 0, 0); BKE_mesh_split_faces(me, true); return me; @@ -783,7 +783,7 @@ static int bake( } /* get the mesh as it arrives in the renderer */ - me_low = bake_mesh_new_from_object(bmain, scene, ob_low); + me_low = bake_mesh_new_from_object(RE_GetEvalCtx(re), bmain, scene, ob_low); /* populate the pixel array with the face data */ if ((is_selected_to_active && (ob_cage == NULL) && is_cage) == false) @@ -798,7 +798,7 @@ static int bake( /* prepare cage mesh */ if (ob_cage) { - me_cage = bake_mesh_new_from_object(bmain, scene, ob_cage); + me_cage = bake_mesh_new_from_object(RE_GetEvalCtx(re), bmain, scene, ob_cage); if ((me_low->totpoly != me_cage->totpoly) || (me_low->totloop != me_cage->totloop)) { BKE_report(reports, RPT_ERROR, "Invalid cage object, the cage mesh must have the same number " @@ -830,7 +830,7 @@ static int bake( ob_low->modifiers = modifiers_tmp; /* get the cage mesh as it arrives in the renderer */ - me_cage = bake_mesh_new_from_object(bmain, scene, ob_low); + me_cage = bake_mesh_new_from_object(RE_GetEvalCtx(re), bmain, scene, ob_low); RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images, uv_layer); } @@ -856,7 +856,7 @@ static int bake( tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED; tmd->ngon_method = MOD_TRIANGULATE_NGON_EARCLIP; - highpoly[i].me = bake_mesh_new_from_object(bmain, scene, highpoly[i].ob); + highpoly[i].me = bake_mesh_new_from_object(RE_GetEvalCtx(re), bmain, scene, highpoly[i].ob); highpoly[i].ob->restrictflag &= ~OB_RESTRICT_RENDER; /* lowpoly to highpoly transformation matrix */ @@ -959,7 +959,7 @@ cage_cleanup: md->mode &= ~eModifierMode_Render; } - me_nores = bake_mesh_new_from_object(bmain, scene, ob_low); + me_nores = bake_mesh_new_from_object(RE_GetEvalCtx(re), bmain, scene, ob_low); RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images, uv_layer); RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_nores, normal_swizzle, ob_low->obmat); diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index d110400de80..0605be5c773 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -775,8 +775,12 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot) /* ------------- Child-Of Constraint ------------------ */ -static void child_get_inverse_matrix(Scene *scene, Object *ob, bConstraint *con, float invmat[4][4], const int owner) +static void child_get_inverse_matrix(const bContext *C, Scene *scene, Object *ob, bConstraint *con, float invmat[4][4], const int owner) { + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); + /* nullify inverse matrix first */ unit_m4(invmat); @@ -802,7 +806,7 @@ static void child_get_inverse_matrix(Scene *scene, Object *ob, bConstraint *con, * to use as baseline ("pmat") to derive delta from. This extra calc saves users * from having pressing "Clear Inverse" first */ - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(&eval_ctx, scene, ob); copy_m4_m4(pmat, pchan->pose_mat); /* 2. knock out constraints starting from this one */ @@ -819,7 +823,7 @@ static void child_get_inverse_matrix(Scene *scene, Object *ob, bConstraint *con, } /* 3. solve pose without disabled constraints */ - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(&eval_ctx, scene, ob); /* 4. determine effect of constraint by removing the newly calculated * pchan->pose_mat from the original pchan->pose_mat, thus determining @@ -842,7 +846,7 @@ static void child_get_inverse_matrix(Scene *scene, Object *ob, bConstraint *con, } /* 6. recalculate pose with new inv-mat applied */ - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(&eval_ctx, scene, ob); } } if (owner == EDIT_CONSTRAINT_OWNER_OBJECT) { @@ -853,7 +857,7 @@ static void child_get_inverse_matrix(Scene *scene, Object *ob, bConstraint *con, BLI_assert(BLI_findindex(&ob->constraints, con) != -1); /* use BKE_object_workob_calc_parent to find inverse - just like for normal parenting */ - BKE_object_workob_calc_parent(scene, ob, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob, &workob); invert_m4_m4(invmat, workob.obmat); } } @@ -875,7 +879,7 @@ static int childof_set_inverse_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - child_get_inverse_matrix(scene, ob, con, data->invmat, owner); + child_get_inverse_matrix(C, scene, ob, con, data->invmat, owner); WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob); @@ -1097,7 +1101,7 @@ static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - child_get_inverse_matrix(scene, ob, con, data->invmat, owner); + child_get_inverse_matrix(C, scene, ob, con, data->invmat, owner); WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob); diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index 9a89ec453fd..3647533eb8f 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -94,9 +94,12 @@ static EnumPropertyItem DT_layer_items[] = { static EnumPropertyItem *dt_layers_select_src_itemf( bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) { + EvaluationContext eval_ctx; EnumPropertyItem *item = NULL, tmp_item = {0}; int totitem = 0; + CTX_data_eval_ctx(C, &eval_ctx); + const int data_type = RNA_enum_get(ptr, "data_type"); if (!C) { /* needed for docs and i18n tools */ @@ -140,7 +143,7 @@ static EnumPropertyItem *dt_layers_select_src_itemf( int num_data, i; /* XXX Is this OK? */ - dm_src = mesh_get_derived_final(scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPUV); + dm_src = mesh_get_derived_final(&eval_ctx, scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPUV); ldata = dm_src->getLoopDataLayout(dm_src); num_data = CustomData_number_of_layers(ldata, CD_MLOOPUV); @@ -163,7 +166,7 @@ static EnumPropertyItem *dt_layers_select_src_itemf( int num_data, i; /* XXX Is this OK? */ - dm_src = mesh_get_derived_final(scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPCOL); + dm_src = mesh_get_derived_final(&eval_ctx, scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPCOL); ldata = dm_src->getLoopDataLayout(dm_src); num_data = CustomData_number_of_layers(ldata, CD_MLOOPCOL); @@ -345,6 +348,9 @@ static int data_transfer_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob_src = ED_object_active_context(C); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); ListBase ctx_objects; CollectionPointerLink *ctx_ob_dst; @@ -413,7 +419,7 @@ static int data_transfer_exec(bContext *C, wmOperator *op) } if (BKE_object_data_transfer_mesh( - scene, ob_src, ob_dst, data_type, use_create, + &eval_ctx, scene, ob_src, ob_dst, data_type, use_create, map_vert_mode, map_edge_mode, map_loop_mode, map_poly_mode, space_transform, use_auto_transform, max_distance, ray_radius, islands_precision, @@ -623,8 +629,11 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob_act = ED_object_active_context(C); + EvaluationContext eval_ctx; DataTransferModifierData *dtmd; + CTX_data_eval_ctx(C, &eval_ctx); + dtmd = (DataTransferModifierData *)edit_modifier_property_get(op, ob_act, eModifierType_DataTransfer); /* If we have a modifier, we transfer data layout from this modifier's source object to active one. @@ -639,7 +648,7 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BKE_object_data_transfer_layout(scene, ob_src, ob_dst, dtmd->data_types, use_delete, + BKE_object_data_transfer_layout(&eval_ctx, scene, ob_src, ob_dst, dtmd->data_types, use_delete, dtmd->layers_select_src, dtmd->layers_select_dst); DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); @@ -669,7 +678,7 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op) for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) { Object *ob_dst = ctx_ob_dst->ptr.data; if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, false)) { - BKE_object_data_transfer_layout(scene, ob_src, ob_dst, data_type, use_delete, + BKE_object_data_transfer_layout(&eval_ctx, scene, ob_src, ob_dst, data_type, use_delete, layers_select_src, layers_select_dst); } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 15bf540fb2f..90de4517a52 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1042,7 +1042,7 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene) CTX_DATA_END; /* recalculate paths, then free */ - animviz_calc_motionpaths(scene, &targets); + animviz_calc_motionpaths(C, scene, &targets); BLI_freelistN(&targets); } diff --git a/source/blender/editors/object/object_hair.c b/source/blender/editors/object/object_hair.c index 6e4f1cfe9f0..b5bcdbb5a3c 100644 --- a/source/blender/editors/object/object_hair.c +++ b/source/blender/editors/object/object_hair.c @@ -65,12 +65,14 @@ static int hair_follicles_generate_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); HairModifierData *hmd = (HairModifierData *)edit_modifier_property_get(op, ob, eModifierType_Hair); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); if (!hmd) return OPERATOR_CANCELLED; CustomDataMask mask = CD_MASK_BAREMESH; - DerivedMesh *scalp = mesh_get_derived_final(scene, ob, mask); + DerivedMesh *scalp = mesh_get_derived_final(&eval_ctx, scene, ob, mask); if (!scalp) return OPERATOR_CANCELLED; diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index fce55689e9a..314019b4f76 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -467,15 +467,18 @@ static Object *add_hook_object_new(Main *bmain, Scene *scene, SceneLayer *sl, Ob return ob; } -static int add_hook_object(Main *bmain, Scene *scene, SceneLayer *sl, Object *obedit, Object *ob, int mode, ReportList *reports) +static int add_hook_object(const bContext *C, Main *bmain, Scene *scene, SceneLayer *sl, Object *obedit, Object *ob, int mode, ReportList *reports) { ModifierData *md = NULL; HookModifierData *hmd = NULL; + EvaluationContext eval_ctx; float cent[3]; float pose_mat[4][4]; int tot, ok, *indexar; char name[MAX_NAME]; + CTX_data_eval_ctx(C, &eval_ctx); + ok = object_hook_index_array(scene, obedit, &tot, &indexar, name, cent); if (!ok) { @@ -544,7 +547,7 @@ static int add_hook_object(Main *bmain, Scene *scene, SceneLayer *sl, Object *ob /* matrix calculus */ /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */ /* (parentinv ) */ - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); invert_m4_m4(ob->imat, ob->obmat); /* apparently this call goes from right to left... */ @@ -584,7 +587,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (add_hook_object(bmain, scene, sl, obedit, obsel, mode, op->reports)) { + if (add_hook_object(C, bmain, scene, sl, obedit, obsel, mode, op->reports)) { WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit); return OPERATOR_FINISHED; } @@ -618,7 +621,7 @@ static int object_add_hook_newob_exec(bContext *C, wmOperator *op) SceneLayer *sl = CTX_data_scene_layer(C); Object *obedit = CTX_data_edit_object(C); - if (add_hook_object(bmain, scene, sl, obedit, NULL, OBJECT_ADDHOOK_NEWOB, op->reports)) { + if (add_hook_object(C, bmain, scene, sl, obedit, NULL, OBJECT_ADDHOOK_NEWOB, op->reports)) { WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit); return OPERATOR_FINISHED; diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 00a94928749..fe68adf1362 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -55,6 +55,7 @@ void OBJECT_OT_scale_clear(struct wmOperatorType *ot); void OBJECT_OT_origin_clear(struct wmOperatorType *ot); void OBJECT_OT_visual_transform_apply(struct wmOperatorType *ot); void OBJECT_OT_transform_apply(struct wmOperatorType *ot); +void OBJECT_OT_transform_axis_target(struct wmOperatorType *ot); void OBJECT_OT_origin_set(struct wmOperatorType *ot); /* object_relations.c */ diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 85751fd64de..6e70734db19 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -522,9 +522,12 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene * return 1; } -static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md) +static int modifier_apply_shape(ReportList *reports, const bContext *C, Scene *scene, Object *ob, ModifierData *md) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); md->scene = scene; @@ -555,7 +558,7 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M return 0; } - dm = mesh_create_derived_for_modifier(scene, ob, md, 0); + dm = mesh_create_derived_for_modifier(&eval_ctx, scene, ob, md, 0); if (!dm) { BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply"); return 0; @@ -582,9 +585,12 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M return 1; } -static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md) +static int modifier_apply_obdata(ReportList *reports, const bContext *C, Scene *scene, Object *ob, ModifierData *md) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); md->scene = scene; @@ -608,13 +614,13 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, multires_force_update(ob); if (mmd && mmd->totlvl && mti->type == eModifierTypeType_OnlyDeform) { - if (!multiresModifier_reshapeFromDeformMod(scene, mmd, ob, md)) { + if (!multiresModifier_reshapeFromDeformMod(&eval_ctx, scene, mmd, ob, md)) { BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply"); return 0; } } else { - dm = mesh_create_derived_for_modifier(scene, ob, md, 1); + dm = mesh_create_derived_for_modifier(&eval_ctx, scene, ob, md, 1); if (!dm) { BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply"); return 0; @@ -640,7 +646,7 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tessellated/bevel vertices"); vertexCos = BKE_curve_nurbs_vertexCos_get(&cu->nurb, &numVerts); - mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0); + mti->deformVerts(md, &eval_ctx, ob, NULL, vertexCos, numVerts, 0); BK_curve_nurbs_vertexCos_apply(&cu->nurb, vertexCos); MEM_freeN(vertexCos); @@ -662,14 +668,14 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, if (psys->part->type != PART_HAIR) continue; - psys_apply_hair_lattice(scene, ob, psys); + psys_apply_hair_lattice(&eval_ctx, scene, ob, psys); } } return 1; } -int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode) +int ED_object_modifier_apply(ReportList *reports, const bContext *C, Scene *scene, Object *ob, ModifierData *md, int mode) { int prev_mode; @@ -697,13 +703,13 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi md->mode |= eModifierMode_Realtime; if (mode == MODIFIER_APPLY_SHAPE) { - if (!modifier_apply_shape(reports, scene, ob, md)) { + if (!modifier_apply_shape(reports, C, scene, ob, md)) { md->mode = prev_mode; return 0; } } else { - if (!modifier_apply_obdata(reports, scene, ob, md)) { + if (!modifier_apply_obdata(reports, C, scene, ob, md)) { md->mode = prev_mode; return 0; } @@ -1003,7 +1009,7 @@ static int modifier_apply_exec(bContext *C, wmOperator *op) ModifierData *md = edit_modifier_property_get(op, ob, 0); int apply_as = RNA_enum_get(op->ptr, "apply_as"); - if (!md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) { + if (!md || !ED_object_modifier_apply(op->reports, C, scene, ob, md, apply_as)) { return OPERATOR_CANCELLED; } @@ -1230,8 +1236,11 @@ static int multires_reshape_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C), *secondob = NULL; Scene *scene = CTX_data_scene(C); + EvaluationContext eval_ctx; MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires); + CTX_data_eval_ctx(C, &eval_ctx); + if (!mmd) return OPERATOR_CANCELLED; @@ -1254,7 +1263,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (!multiresModifier_reshape(scene, mmd, ob, secondob)) { + if (!multiresModifier_reshape(&eval_ctx, scene, mmd, ob, secondob)) { BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices"); return OPERATOR_CANCELLED; } @@ -1687,8 +1696,10 @@ static void skin_armature_bone_create(Object *skin_ob, } } -static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, SceneLayer *sl, Object *skin_ob) +static Object *modifier_skin_armature_create(const bContext *C, Scene *scene, SceneLayer *sl, Object *skin_ob) { + Main *bmain = CTX_data_main(C); + EvaluationContext eval_ctx; BLI_bitmap *edges_visited; DerivedMesh *deform_dm; MVert *mvert; @@ -1700,7 +1711,9 @@ static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, SceneLay int *emap_mem; int v; - deform_dm = mesh_get_derived_deform(scene, skin_ob, CD_MASK_BAREMESH); + CTX_data_eval_ctx(C, &eval_ctx); + + deform_dm = mesh_get_derived_deform(&eval_ctx, scene, skin_ob, CD_MASK_BAREMESH); mvert = deform_dm->getVertArray(deform_dm); /* add vertex weights to original mesh */ @@ -1781,7 +1794,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op) } /* create new armature */ - arm_ob = modifier_skin_armature_create(bmain, scene, sl, ob); + arm_ob = modifier_skin_armature_create(C, scene, sl, ob); /* add a modifier to connect the new armature to the mesh */ arm_md = (ArmatureModifierData *)modifier_new(eModifierType_Armature); @@ -1901,8 +1914,11 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); + EvaluationContext eval_ctx; MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform); + CTX_data_eval_ctx(C, &eval_ctx); + if (!mmd) return OPERATOR_CANCELLED; @@ -1940,17 +1956,17 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op) mmd->modifier.mode |= eModifierMode_Realtime; if (ob->type == OB_MESH) { - dm = mesh_create_derived_view(scene, ob, 0); + dm = mesh_create_derived_view(&eval_ctx, scene, ob, 0); dm->release(dm); } else if (ob->type == OB_LATTICE) { - BKE_lattice_modifiers_calc(scene, ob); + BKE_lattice_modifiers_calc(&eval_ctx, scene, ob); } else if (ob->type == OB_MBALL) { - BKE_displist_make_mball(CTX_data_main(C)->eval_ctx, scene, ob); + BKE_displist_make_mball(&eval_ctx, scene, ob); } else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { - BKE_displist_make_curveTypes(scene, ob, 0); + BKE_displist_make_curveTypes(&eval_ctx, scene, ob, 0); } mmd->bindfunc = NULL; diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 7204ed820ce..66e54c1436b 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -61,6 +61,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_origin_clear); WM_operatortype_append(OBJECT_OT_visual_transform_apply); WM_operatortype_append(OBJECT_OT_transform_apply); + WM_operatortype_append(OBJECT_OT_transform_axis_target); WM_operatortype_append(OBJECT_OT_origin_set); WM_operatortype_append(OBJECT_OT_mode_set); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 333bcf00a8c..8b4eb794820 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -129,6 +129,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); SceneLayer *sl = CTX_data_scene_layer(C); Object *obedit = CTX_data_edit_object(C); + EvaluationContext eval_ctx; BMVert *eve; BMIter iter; Curve *cu; @@ -138,6 +139,8 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) Object *par; int a, v1 = 0, v2 = 0, v3 = 0, v4 = 0, nr = 1; + CTX_data_eval_ctx(C, &eval_ctx); + /* we need 1 to 3 selected vertices */ if (obedit->type == OB_MESH) { @@ -156,7 +159,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) /* derivedMesh might be needed for solving parenting, * so re-create it here */ - makeDerivedMesh(scene, obedit, em, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX, false); + makeDerivedMesh(&eval_ctx, scene, obedit, em, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX, false); BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { @@ -252,7 +255,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) ob->par3 = v3 - 1; /* inverse parent matrix */ - BKE_object_workob_calc_parent(scene, ob, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); } else { @@ -260,7 +263,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) ob->par1 = v1 - 1; /* inverse parent matrix */ - BKE_object_workob_calc_parent(scene, ob, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); } } @@ -612,12 +615,16 @@ EnumPropertyItem prop_make_parent_types[] = { {0, NULL, 0, NULL, NULL} }; -bool ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object *ob, Object *par, +bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene, Object *ob, Object *par, int partype, const bool xmirror, const bool keep_transform, const int vert_par[3]) { + Main *bmain = CTX_data_main(C); + EvaluationContext eval_ctx; bPoseChannel *pchan = NULL; const bool pararm = ELEM(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO); + CTX_data_eval_ctx(C, &eval_ctx); + DEG_id_tag_update(&par->id, OB_RECALC_OB); /* preconditions */ @@ -629,7 +636,7 @@ bool ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object if ((cu->flag & CU_PATH) == 0) { cu->flag |= CU_PATH | CU_FOLLOW; - BKE_displist_make_curveTypes(scene, par, 0); /* force creation of path data */ + BKE_displist_make_curveTypes(&eval_ctx, scene, par, 0); /* force creation of path data */ } else { cu->flag |= CU_FOLLOW; @@ -771,30 +778,30 @@ bool ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object data = con->data; data->tar = par; - BKE_constraint_target_matrix_get(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra); + BKE_constraint_target_matrix_get(&eval_ctx, scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra); sub_v3_v3v3(vec, ob->obmat[3], cmat[3]); copy_v3_v3(ob->loc, vec); } else if (pararm && (ob->type == OB_MESH) && (par->type == OB_ARMATURE)) { if (partype == PAR_ARMATURE_NAME) - create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_NAME, false); + create_vgroups_from_armature(reports, C, scene, ob, par, ARM_GROUPS_NAME, false); else if (partype == PAR_ARMATURE_ENVELOPE) - create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_ENVELOPE, xmirror); + create_vgroups_from_armature(reports, C, scene, ob, par, ARM_GROUPS_ENVELOPE, xmirror); else if (partype == PAR_ARMATURE_AUTO) { WM_cursor_wait(1); - create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_AUTO, xmirror); + create_vgroups_from_armature(reports, C, scene, ob, par, ARM_GROUPS_AUTO, xmirror); WM_cursor_wait(0); } /* get corrected inverse */ ob->partype = PAROBJECT; - BKE_object_workob_calc_parent(scene, ob, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); } else { /* calculate inverse parent matrix */ - BKE_object_workob_calc_parent(scene, ob, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); } @@ -869,7 +876,7 @@ static int parent_set_exec(bContext *C, wmOperator *op) parent_set_vert_find(tree, ob, vert_par, is_tri); } - if (!ED_object_parent_set(op->reports, bmain, scene, ob, par, partype, xmirror, keep_transform, vert_par_p)) { + if (!ED_object_parent_set(op->reports, C, scene, ob, par, partype, xmirror, keep_transform, vert_par_p)) { ok = false; break; } @@ -1052,13 +1059,16 @@ void OBJECT_OT_parent_no_inverse_set(wmOperatorType *ot) static int object_slow_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { if (ob->parent) { if (ob->partype & PARSLOW) { ob->partype -= PARSLOW; - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); ob->partype |= PARSLOW; DEG_id_tag_update(&ob->id, OB_RECALC_OB); } diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 542b98d771f..cf68bd3e419 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -39,10 +39,12 @@ #include "DNA_scene_types.h" #include "DNA_group_types.h" #include "DNA_lattice_types.h" +#include "DNA_lamp_types.h" #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" +#include "BLI_array.h" #include "BKE_context.h" #include "BKE_curve.h" @@ -72,6 +74,8 @@ #include "ED_screen.h" #include "ED_view3d.h" +#include "MEM_guardedalloc.h" + #include "object_intern.h" /*************************** Clear Transformation ****************************/ @@ -400,16 +404,19 @@ void OBJECT_OT_origin_clear(wmOperatorType *ot) /* use this when the loc/size/rot of the parent has changed but the children * should stay in the same place, e.g. for apply-size-rot or object center */ -static void ignore_parent_tx(Main *bmain, Scene *scene, Object *ob) +static void ignore_parent_tx(const bContext *C, Main *bmain, Scene *scene, Object *ob) { Object workob; Object *ob_child; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); /* a change was made, adjust the children to compensate */ for (ob_child = bmain->object.first; ob_child; ob_child = ob_child->id.next) { if (ob_child->parent == ob) { BKE_object_apply_mat4(ob_child, ob_child->obmat, true, false); - BKE_object_workob_calc_parent(scene, ob_child, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob_child, &workob); invert_m4_m4(ob_child->parentinv, workob.obmat); } } @@ -419,8 +426,11 @@ static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_l { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + EvaluationContext eval_ctx; float rsmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale; bool changed = true; + + CTX_data_eval_ctx(C, &eval_ctx); /* first check if we can execute */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) @@ -523,7 +533,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_l Mesh *me = ob->data; if (apply_scale) - multiresModifier_scale_disp(scene, ob); + multiresModifier_scale_disp(&eval_ctx, scene, ob); /* adjust data */ BKE_mesh_transform(me, mat, true); @@ -611,12 +621,12 @@ static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_l unit_axis_angle(ob->rotAxis, &ob->rotAngle); } - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); if (ob->type == OB_ARMATURE) { - BKE_pose_where_is(scene, ob); /* needed for bone parents */ + BKE_pose_where_is(&eval_ctx, scene, ob); /* needed for bone parents */ } - ignore_parent_tx(bmain, scene, ob); + ignore_parent_tx(C, bmain, scene, ob); DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA); @@ -636,13 +646,16 @@ static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_l static int visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); + EvaluationContext eval_ctx; bool changed = false; + CTX_data_eval_ctx(C, &eval_ctx); + CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); BKE_object_apply_mat4(ob, ob->obmat, true, true); - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); /* update for any children that may get moved */ DEG_id_tag_update(&ob->id, OB_RECALC_OB); @@ -722,6 +735,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *obact = CTX_data_active_object(C); Object *obedit = CTX_data_edit_object(C); + EvaluationContext eval_ctx; Object *tob; float cursor[3], cent[3], cent_neg[3], centn[3]; int centermode = RNA_enum_get(op->ptr, "type"); @@ -731,6 +745,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) CollectionPointerLink *ctx_ob; CollectionPointerLink *ctx_ob_act = NULL; + CTX_data_eval_ctx(C, &eval_ctx); + /* keep track of what is changed */ int tot_change = 0, tot_lib_error = 0, tot_multiuser_arm_error = 0; @@ -924,8 +940,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) cent[2] = 0.0f; - cu->xof = cu->xof - (cent[0] / cu->fsize); - cu->yof = cu->yof - (cent[1] / cu->fsize); + cu->xof = cu->xof - cent[0]; + cu->yof = cu->yof - cent[1]; tot_change++; cu->id.tag |= LIB_TAG_DOIT; @@ -952,10 +968,10 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) arm->id.tag |= LIB_TAG_DOIT; /* do_inverse_offset = true; */ /* docenter_armature() handles this */ - BKE_object_where_is_calc(scene, ob); - BKE_pose_where_is(scene, ob); /* needed for bone parents */ + BKE_object_where_is_calc(&eval_ctx, scene, ob); + BKE_pose_where_is(&eval_ctx, scene, ob); /* needed for bone parents */ - ignore_parent_tx(bmain, scene, ob); + ignore_parent_tx(C, bmain, scene, ob); if (obedit) break; @@ -1011,12 +1027,12 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) add_v3_v3(ob->loc, centn); - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); if (ob->type == OB_ARMATURE) { - BKE_pose_where_is(scene, ob); /* needed for bone parents */ + BKE_pose_where_is(&eval_ctx, scene, ob); /* needed for bone parents */ } - ignore_parent_tx(bmain, scene, ob); + ignore_parent_tx(C, bmain, scene, ob); /* other users? */ //CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects) @@ -1040,11 +1056,11 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) mul_v3_mat3_m4v3(centn, ob_other->obmat, cent); /* omit translation part */ add_v3_v3(ob_other->loc, centn); - BKE_object_where_is_calc(scene, ob_other); + BKE_object_where_is_calc(&eval_ctx, scene, ob_other); if (ob_other->type == OB_ARMATURE) { - BKE_pose_where_is(scene, ob_other); /* needed for bone parents */ + BKE_pose_where_is(&eval_ctx, scene, ob_other); /* needed for bone parents */ } - ignore_parent_tx(bmain, scene, ob_other); + ignore_parent_tx(C, bmain, scene, ob_other); } } //CTX_DATA_END; @@ -1112,3 +1128,385 @@ void OBJECT_OT_origin_set(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", prop_set_center_types, 0, "Type", ""); RNA_def_enum(ot->srna, "center", prop_set_bounds_types, V3D_AROUND_CENTER_MEAN, "Center", ""); } + +/* -------------------------------------------------------------------- */ + +/** \name Transform Axis Target + * + * Note this is an experemental operator to point lamps/cameras at objects. + * We may re-work how this behaves based on user feedback. + * - campbell. + * \{ */ + +/* When using multiple objects, apply their relative rotational offset to the active object. */ +#define USE_RELATIVE_ROTATION + +struct XFormAxisItem { + Object *ob; + float rot_mat[3][3]; + void *obtfm; + float xform_dist; + +#ifdef USE_RELATIVE_ROTATION + /* use when translating multiple */ + float xform_rot_offset[3][3]; +#endif +}; + +struct XFormAxisData { + ViewContext vc; + struct { + float depth; + float normal[3]; + bool is_depth_valid; + bool is_normal_valid; + } prev; + + struct XFormAxisItem *object_data; + uint object_data_len; + bool is_translate; + + int init_event; +}; + +static bool object_is_target_compat(const Object *ob) +{ + if (ob->type == OB_LAMP) { + const Lamp *la = ob->data; + if (ELEM(la->type, LA_SUN, LA_SPOT, LA_HEMI, LA_AREA)) { + return true; + } + } + /* We might want to enable this later, for now just lamps */ +#if 0 + else if (ob->type == OB_CAMERA) { + return true; + } +#endif + return false; +} + +static void object_transform_axis_target_free_data(wmOperator *op) +{ + struct XFormAxisData *xfd = op->customdata; + struct XFormAxisItem *item = xfd->object_data; + for (int i = 0; i < xfd->object_data_len; i++, item++) { + MEM_freeN(item->obtfm); + } + MEM_freeN(xfd->object_data); + MEM_freeN(xfd); + op->customdata = NULL; +} + +/* We may want to expose as alternative to: BKE_object_apply_rotation */ +static void object_apply_rotation(Object *ob, const float rmat[3][3]) +{ + float size[3]; + float loc[3]; + float rmat4[4][4]; + copy_m4_m3(rmat4, rmat); + + copy_v3_v3(size, ob->size); + copy_v3_v3(loc, ob->loc); + BKE_object_apply_mat4(ob, rmat4, true, true); + copy_v3_v3(ob->size, size); + copy_v3_v3(ob->loc, loc); +} +/* We may want to extract this to: BKE_object_apply_location */ +static void object_apply_location(Object *ob, const float loc[3]) +{ + /* quick but weak */ + Object ob_prev = *ob; + float mat[4][4]; + copy_m4_m4(mat, ob->obmat); + copy_v3_v3(mat[3], loc); + BKE_object_apply_mat4(ob, mat, true, true); + copy_v3_v3(mat[3], ob->loc); + *ob = ob_prev; + copy_v3_v3(ob->loc, mat[3]); +} + +static void object_orient_to_location( + Object *ob, float rot_orig[3][3], const float axis[3], const float location[3]) +{ + float delta[3]; + sub_v3_v3v3(delta, ob->obmat[3], location); + if (normalize_v3(delta) != 0.0f) { + if (len_squared_v3v3(delta, axis) > FLT_EPSILON) { + float delta_rot[3][3]; + float final_rot[3][3]; + rotation_between_vecs_to_mat3(delta_rot, axis, delta); + + mul_m3_m3m3(final_rot, delta_rot, rot_orig); + + object_apply_rotation(ob, final_rot); + + DEG_id_tag_update(&ob->id, OB_RECALC_OB); + } + } +} + +static void object_transform_axis_target_cancel(bContext *C, wmOperator *op) +{ + struct XFormAxisData *xfd = op->customdata; + struct XFormAxisItem *item = xfd->object_data; + for (int i = 0; i < xfd->object_data_len; i++, item++) { + BKE_object_tfm_restore(item->ob, item->obtfm); + DEG_id_tag_update(&item->ob->id, OB_RECALC_OB); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item->ob); + } + + object_transform_axis_target_free_data(op); +} + +static int object_transform_axis_target_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ViewContext vc; + view3d_set_viewcontext(C, &vc); + + if (!object_is_target_compat(vc.obact)) { + /* Falls back to texture space transform. */ + return OPERATOR_PASS_THROUGH; + } + + ED_view3d_autodist_init(C, vc.depsgraph, vc.ar, vc.v3d, 0); + + if (vc.rv3d->depths != NULL) { + vc.rv3d->depths->damaged = true; + } + ED_view3d_depth_update(vc.ar); + + if (vc.rv3d->depths == NULL) { + BKE_report(op->reports, RPT_WARNING, "Unable to access depth buffer, using view plane"); + return OPERATOR_CANCELLED; + } + + ED_region_tag_redraw(vc.ar); + + struct XFormAxisData *xfd; + xfd = op->customdata = MEM_callocN(sizeof(struct XFormAxisData), __func__); + + /* Don't change this at runtime. */ + xfd->vc = vc; + xfd->vc.mval[0] = event->mval[0]; + xfd->vc.mval[1] = event->mval[1]; + + xfd->prev.depth = 1.0f; + xfd->prev.is_depth_valid = false; + xfd->prev.is_normal_valid = false; + xfd->is_translate = false; + + xfd->init_event = WM_userdef_event_type_from_keymap_type(event->type); + + { + struct XFormAxisItem *object_data = NULL; + BLI_array_declare(object_data); + + struct XFormAxisItem *item = BLI_array_append_ret(object_data); + item->ob = xfd->vc.obact; + + CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + { + if ((ob != xfd->vc.obact) && object_is_target_compat(ob)) { + item = BLI_array_append_ret(object_data); + item->ob = ob; + } + } + CTX_DATA_END; + + xfd->object_data = object_data; + xfd->object_data_len = BLI_array_count(object_data); + + if (xfd->object_data_len != BLI_array_count(object_data)) { + xfd->object_data = MEM_reallocN(xfd->object_data, xfd->object_data_len * sizeof(*xfd->object_data)); + } + } + + { + struct XFormAxisItem *item = xfd->object_data; + for (int i = 0; i < xfd->object_data_len; i++, item++) { + item->obtfm = BKE_object_tfm_backup(item->ob); + BKE_object_rot_to_mat3(item->ob, item->rot_mat, true); + } + } + + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + struct XFormAxisData *xfd = op->customdata; + ARegion *ar = xfd->vc.ar; + + view3d_operator_needs_opengl(C); + + const bool is_translate = (event->ctrl != 0); + const bool is_translate_init = is_translate && (xfd->is_translate != is_translate); + + if (event->type == MOUSEMOVE || is_translate_init) { + const ViewDepths *depths = xfd->vc.rv3d->depths; + if (depths && + ((unsigned int)event->mval[0] < depths->w) && + ((unsigned int)event->mval[1] < depths->h)) + { + double depth = (double)ED_view3d_depth_read_cached(&xfd->vc, event->mval); + float location_world[3]; + if (depth == 1.0f) { + if (xfd->prev.is_depth_valid) { + depth = (double)xfd->prev.depth; + } + } + if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) { + xfd->prev.depth = depth; + xfd->prev.is_depth_valid = true; + if (ED_view3d_depth_unproject(ar, event->mval, depth, location_world)) { + if (is_translate) { + + float normal[3]; + bool normal_found = false; + if (ED_view3d_depth_read_cached_normal(&xfd->vc, event->mval, normal)) { + normal_found = true; + + /* cheap attempt to smooth normals out a bit! */ + const uint ofs = 2; + for (uint x = -ofs; x <= ofs; x += ofs / 2) { + for (uint y = -ofs; y <= ofs; y += ofs / 2) { + if (x != 0 && y != 0) { + int mval_ofs[2] = {event->mval[0] + x, event->mval[1] + y}; + float n[3]; + if (ED_view3d_depth_read_cached_normal( + &xfd->vc, mval_ofs, n)) + { + add_v3_v3(normal, n); + } + } + } + } + normalize_v3(normal); + } + else if (xfd->prev.is_normal_valid) { + copy_v3_v3(normal, xfd->prev.normal); + normal_found = true; + } + + if (normal_found) { +#ifdef USE_RELATIVE_ROTATION + if (is_translate_init && xfd->object_data_len > 1) { + float xform_rot_offset_inv_first[3][3]; + struct XFormAxisItem *item = xfd->object_data; + for (int i = 0; i < xfd->object_data_len; i++, item++) { + copy_m3_m4(item->xform_rot_offset, item->ob->obmat); + normalize_m3(item->xform_rot_offset); + + if (i == 0) { + invert_m3_m3(xform_rot_offset_inv_first, xfd->object_data[0].xform_rot_offset); + } + else { + mul_m3_m3m3(item->xform_rot_offset, + item->xform_rot_offset, + xform_rot_offset_inv_first); + } + } + } + +#endif + + struct XFormAxisItem *item = xfd->object_data; + for (int i = 0; i < xfd->object_data_len; i++, item++) { + if (is_translate_init) { + float ob_axis[3]; + item->xform_dist = len_v3v3(item->ob->obmat[3], location_world); + normalize_v3_v3(ob_axis, item->ob->obmat[2]); + /* Scale to avoid adding distance when moving between surfaces. */ + float scale = fabsf(dot_v3v3(ob_axis, normal)); + item->xform_dist *= scale; + } + + float target_normal[3]; + copy_v3_v3(target_normal, normal); + +#ifdef USE_RELATIVE_ROTATION + if (i != 0) { + mul_m3_v3(item->xform_rot_offset, target_normal); + } +#endif + { + float loc[3]; + + copy_v3_v3(loc, location_world); + madd_v3_v3fl(loc, target_normal, item->xform_dist); + object_apply_location(item->ob, loc); + copy_v3_v3(item->ob->obmat[3], loc); /* so orient behaves as expected */ + } + + object_orient_to_location(item->ob, item->rot_mat, item->rot_mat[2], location_world); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item->ob); + } + copy_v3_v3(xfd->prev.normal, normal); + xfd->prev.is_normal_valid = true; + } + } + else { + struct XFormAxisItem *item = xfd->object_data; + for (int i = 0; i < xfd->object_data_len; i++, item++) { + object_orient_to_location(item->ob, item->rot_mat, item->rot_mat[2], location_world); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item->ob); + } + xfd->prev.is_normal_valid = false; + } + } + } + } + xfd->is_translate = is_translate; + + ED_region_tag_redraw(xfd->vc.ar); + } + + bool is_finished = false; + + if (ISMOUSE(xfd->init_event)) { + if ((event->type == xfd->init_event) && (event->val == KM_RELEASE)) { + is_finished = true; + } + } + else { + if (ELEM(event->type, LEFTMOUSE, RETKEY, PADENTER)) { + is_finished = true; + } + } + + if (is_finished) { + object_transform_axis_target_free_data(op); + return OPERATOR_FINISHED; + } + else if (ELEM(event->type, ESCKEY, RIGHTMOUSE)) { + object_transform_axis_target_cancel(C, op); + return OPERATOR_CANCELLED; + } + + + return OPERATOR_RUNNING_MODAL; +} + +void OBJECT_OT_transform_axis_target(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Interactive Lamp Track to Cursor"; + ot->description = "Interactively point cameras and lamps to a location (Ctrl translates)"; + ot->idname = "OBJECT_OT_transform_axis_target"; + + /* api callbacks */ + ot->invoke = object_transform_axis_target_invoke; + ot->cancel = object_transform_axis_target_cancel; + ot->modal = object_transform_axis_target_modal; + ot->poll = ED_operator_region_view3d_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; +} + +#undef USE_RELATIVE_ROTATION + +/** \} */ diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 51723ac14d3..84a8d36db3c 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -1257,9 +1257,9 @@ static void dm_deform_clear(DerivedMesh *dm, Object *ob) } /* recalculate the deformation */ -static DerivedMesh *dm_deform_recalc(Scene *scene, Object *ob) +static DerivedMesh *dm_deform_recalc(EvaluationContext *eval_ctx, Scene *scene, Object *ob) { - return mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); + return mesh_get_derived_deform(eval_ctx, scene, ob, CD_MASK_BAREMESH); } /* by changing nonzero weights, try to move a vertex in me->mverts with index 'index' to @@ -1271,7 +1271,7 @@ static DerivedMesh *dm_deform_recalc(Scene *scene, Object *ob) * norm and d are the plane's properties for the equation: ax + by + cz + d = 0 * coord is a point on the plane */ -static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, int index, float norm[3], +static void moveCloserToDistanceFromPlane(EvaluationContext *eval_ctx, Scene *scene, Object *ob, Mesh *me, int index, float norm[3], float coord[3], float d, float distToBe, float strength, float cp) { DerivedMesh *dm; @@ -1298,7 +1298,7 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in float originalDistToBe = distToBe; do { wasChange = false; - dm = dm_deform_recalc(scene, ob); + dm = dm_deform_recalc(eval_ctx, scene, ob); dm->getVert(dm, index, &m); copy_v3_v3(oldPos, m.co); distToStart = dot_v3v3(norm, oldPos) + d; @@ -1336,7 +1336,7 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in if (dw->weight > 1) { dw->weight = 1; } - dm = dm_deform_recalc(scene, ob); + dm = dm_deform_recalc(eval_ctx, scene, ob); dm->getVert(dm, index, &m); getVerticalAndHorizontalChange(norm, d, coord, oldPos, distToStart, m.co, changes, dists, i); dw->weight = oldw; @@ -1446,10 +1446,13 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in /* this is used to try to smooth a surface by only adjusting the nonzero weights of a vertex * but it could be used to raise or lower an existing 'bump.' */ -static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength, float cp) +static void vgroup_fix(const bContext *C, Scene *scene, Object *ob, float distToBe, float strength, float cp) { + EvaluationContext eval_ctx; int i; + CTX_data_eval_ctx(C, &eval_ctx); + Mesh *me = ob->data; MVert *mvert = me->mvert; int *verts = NULL; @@ -1463,7 +1466,7 @@ static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength, MVert *p = MEM_callocN(sizeof(MVert) * (count), "deformedPoints"); int k; - DerivedMesh *dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); + DerivedMesh *dm = mesh_get_derived_deform(&eval_ctx, scene, ob, CD_MASK_BAREMESH); k = count; while (k--) { dm->getVert(dm, verts[k], &m); @@ -1481,7 +1484,7 @@ static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength, if (mag) { /* zeros fix */ d = -dot_v3v3(norm, coord); /* dist = (dot_v3v3(norm, m.co) + d); */ /* UNUSED */ - moveCloserToDistanceFromPlane(scene, ob, me, i, norm, coord, d, distToBe, strength, cp); + moveCloserToDistanceFromPlane(&eval_ctx, scene, ob, me, i, norm, coord, d, distToBe, strength, cp); } } @@ -2975,7 +2978,7 @@ static int vertex_group_fix_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "This operator does not support an active mirror modifier"); return OPERATOR_CANCELLED; } - vgroup_fix(scene, ob, distToBe, strength, cp); + vgroup_fix(C, scene, ob, distToBe, strength, cp); DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index cd07b57577b..1f0ee6862d2 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -294,6 +294,8 @@ typedef struct DynamicPaintBakeJob { DynamicPaintSurface *surface; DynamicPaintCanvasSettings *canvas; + EvaluationContext *eval_ctx; + int success; double start; } DynamicPaintBakeJob; @@ -313,6 +315,8 @@ static void dpaint_bake_endjob(void *customdata) dynamicPaint_freeSurfaceData(job->surface); + MEM_freeN(job->eval_ctx); + G.is_rendering = false; BKE_spacedata_draw_locks(false); @@ -387,7 +391,7 @@ static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job) /* calculate a frame */ scene->r.cfra = (int)frame; ED_update_for_newframe(job->bmain, scene, 1); - if (!dynamicPaint_calculateFrame(surface, scene, job->scene_layer, cObject, frame)) { + if (!dynamicPaint_calculateFrame(surface, job->eval_ctx, scene, cObject, frame)) { job->success = 0; return; } @@ -456,6 +460,9 @@ static int dynamicpaint_bake_exec(struct bContext *C, struct wmOperator *op) Object *ob = ED_object_context(C); Scene *scene = CTX_data_scene(C); SceneLayer *sl = CTX_data_scene_layer(C); + EvaluationContext *eval_ctx = MEM_mallocN(sizeof(*eval_ctx), "EvaluationContext"); + + CTX_data_eval_ctx(C, eval_ctx); DynamicPaintSurface *surface; @@ -487,6 +494,7 @@ static int dynamicpaint_bake_exec(struct bContext *C, struct wmOperator *op) job->ob = ob; job->canvas = canvas; job->surface = surface; + job->eval_ctx = eval_ctx; wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Dynamic Paint Bake", WM_JOB_PROGRESS, diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index fb3cfdc86b2..ca454cca576 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -86,7 +86,7 @@ #include "physics_intern.h" -void PE_create_particle_edit(Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys); +void PE_create_particle_edit(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys); void PTCacheUndo_clear(PTCacheEdit *edit); void recalc_lengths(PTCacheEdit *edit); void recalc_emitter_field(Object *ob, ParticleSystem *psys); @@ -216,7 +216,7 @@ static float pe_brush_size_get(const Scene *UNUSED(scene), ParticleBrushData *br * * note: this function runs on poll, therefor it can runs many times a second * keep it fast! */ -static PTCacheEdit *pe_get_current(Scene *scene, SceneLayer *sl, Object *ob, int create) +static PTCacheEdit *pe_get_current(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, int create) { ParticleEditSettings *pset= PE_settings(scene); PTCacheEdit *edit = NULL; @@ -256,18 +256,18 @@ static PTCacheEdit *pe_get_current(Scene *scene, SceneLayer *sl, Object *ob, int if (psys->part && psys->part->type == PART_HAIR) { if (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED) { if (create && !psys->pointcache->edit) - PE_create_particle_edit(scene, sl, ob, pid->cache, NULL); + PE_create_particle_edit(C, scene, sl, ob, pid->cache, NULL); edit = pid->cache->edit; } else { if (create && !psys->edit && psys->flag & PSYS_HAIR_DONE) - PE_create_particle_edit(scene, sl, ob, NULL, psys); + PE_create_particle_edit(C, scene, sl, ob, NULL, psys); edit = psys->edit; } } else { if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) - PE_create_particle_edit(scene, sl, ob, pid->cache, psys); + PE_create_particle_edit(C, scene, sl, ob, pid->cache, psys); edit = pid->cache->edit; } @@ -278,7 +278,7 @@ static PTCacheEdit *pe_get_current(Scene *scene, SceneLayer *sl, Object *ob, int if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) { pset->flag |= PE_FADE_TIME; // NICE TO HAVE but doesn't work: pset->brushtype = PE_BRUSH_COMB; - PE_create_particle_edit(scene, sl, ob, pid->cache, NULL); + PE_create_particle_edit(C, scene, sl, ob, pid->cache, NULL); } edit = pid->cache->edit; break; @@ -287,7 +287,7 @@ static PTCacheEdit *pe_get_current(Scene *scene, SceneLayer *sl, Object *ob, int if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) { pset->flag |= PE_FADE_TIME; // NICE TO HAVE but doesn't work: pset->brushtype = PE_BRUSH_COMB; - PE_create_particle_edit(scene, sl, ob, pid->cache, NULL); + PE_create_particle_edit(C, scene, sl, ob, pid->cache, NULL); } edit = pid->cache->edit; break; @@ -304,18 +304,18 @@ static PTCacheEdit *pe_get_current(Scene *scene, SceneLayer *sl, Object *ob, int PTCacheEdit *PE_get_current(Scene *scene, SceneLayer *sl, Object *ob) { - return pe_get_current(scene, sl, ob, 0); + return pe_get_current(NULL, scene, sl, ob, 0); } -PTCacheEdit *PE_create_current(Scene *scene, Object *ob) +PTCacheEdit *PE_create_current(const bContext *C, Scene *scene, Object *ob) { - return pe_get_current(scene, NULL, ob, 1); + return pe_get_current(C, scene, NULL, ob, 1); } -void PE_current_changed(Scene *scene, Object *ob) +void PE_current_changed(const bContext *C, Scene *scene, Object *ob) { if (ob->mode == OB_MODE_PARTICLE_EDIT) - PE_create_current(scene, ob); + PE_create_current(C, scene, ob); } void PE_hide_keys_time(Scene *scene, PTCacheEdit *edit, float cfra) @@ -358,6 +358,7 @@ static int pe_x_mirror(Object *ob) typedef struct PEData { ViewContext vc; + const bContext *context; Scene *scene; SceneLayer *scene_layer; Object *ob; @@ -393,10 +394,10 @@ static void PE_set_data(bContext *C, PEData *data) { memset(data, 0, sizeof(*data)); - data->scene= CTX_data_scene(C); + data->scene = CTX_data_scene(C); data->scene_layer = CTX_data_scene_layer(C); - data->ob= CTX_data_active_object(C); - data->edit= PE_get_current(data->scene, data->scene_layer, data->ob); + data->ob = CTX_data_active_object(C); + data->edit = PE_get_current(data->scene, data->scene_layer, data->ob); } static void PE_set_view3d_data(bContext *C, PEData *data) @@ -410,7 +411,7 @@ static void PE_set_view3d_data(bContext *C, PEData *data) /* needed or else the draw matrix can be incorrect */ view3d_operator_needs_opengl(C); - ED_view3d_backbuf_validate(&data->vc); + ED_view3d_backbuf_validate(C, &data->vc); /* we may need to force an update here by setting the rv3d as dirty * for now it seems ok, but take care!: * rv3d->depths->dirty = 1; */ @@ -1156,12 +1157,15 @@ void recalc_emitter_field(Object *ob, ParticleSystem *psys) BLI_kdtree_balance(edit->emitter_field); } -static void PE_update_selection(Scene *scene, SceneLayer *sl, Object *ob, int useflag) +static void PE_update_selection(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, int useflag) { - PTCacheEdit *edit= PE_get_current(scene, sl, ob); + PTCacheEdit *edit = PE_get_current(scene, sl, ob); HairKey *hkey; + EvaluationContext eval_ctx; POINT_P; KEY_K; + CTX_data_eval_ctx(C, &eval_ctx); + /* flag all particles to be updated if not using flag */ if (!useflag) LOOP_POINTS @@ -1177,7 +1181,7 @@ static void PE_update_selection(Scene *scene, SceneLayer *sl, Object *ob, int us } } - psys_cache_edit_paths(scene, ob, edit, CFRA, G.is_rendering); + psys_cache_edit_paths(&eval_ctx, scene, ob, edit, CFRA, G.is_rendering); /* disable update flag */ @@ -1263,17 +1267,20 @@ static void update_velocities(PTCacheEdit *edit) } } -void PE_update_object(Scene *scene, SceneLayer *sl, Object *ob, int useflag) +void PE_update_object(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, int useflag) { /* use this to do partial particle updates, not usable when adding or * removing, then a full redo is necessary and calling this may crash */ ParticleEditSettings *pset= PE_settings(scene); PTCacheEdit *edit = PE_get_current(scene, sl, ob); + EvaluationContext eval_ctx; POINT_P; if (!edit) return; + CTX_data_eval_ctx(C, &eval_ctx); + /* flag all particles to be updated if not using flag */ if (!useflag) LOOP_POINTS { @@ -1293,7 +1300,7 @@ void PE_update_object(Scene *scene, SceneLayer *sl, Object *ob, int useflag) PE_hide_keys_time(scene, edit, CFRA); /* regenerate path caches */ - psys_cache_edit_paths(scene, ob, edit, CFRA, G.is_rendering); + psys_cache_edit_paths(&eval_ctx, scene, ob, edit, CFRA, G.is_rendering); /* disable update flag */ LOOP_POINTS { @@ -1428,7 +1435,7 @@ static int pe_select_all_exec(bContext *C, wmOperator *op) } } - PE_update_selection(scene, sl, ob, 1); + PE_update_selection(C, scene, sl, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1461,7 +1468,7 @@ int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselec Object *ob= CTX_data_active_object(C); PTCacheEdit *edit= PE_get_current(scene, sl, ob); POINT_P; KEY_K; - + if (!PE_start_edit(edit)) return OPERATOR_CANCELLED; @@ -1486,7 +1493,7 @@ int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselec else for_mouse_hit_keys(&data, toggle_key_select, 1); - PE_update_selection(scene, sl, ob, 1); + PE_update_selection(C, scene, sl, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1527,7 +1534,7 @@ static int select_roots_exec(bContext *C, wmOperator *op) data.select_action = action; foreach_point(&data, select_root); - PE_update_selection(data.scene, data.scene_layer, data.ob, 1); + PE_update_selection(C, data.scene, data.scene_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1592,7 +1599,7 @@ static int select_tips_exec(bContext *C, wmOperator *op) data.select_action = action; foreach_point(&data, select_tip); - PE_update_selection(data.scene, data.scene_layer, data.ob, 1); + PE_update_selection(C, data.scene, data.scene_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1678,7 +1685,7 @@ static int select_random_exec(bContext *C, wmOperator *op) BLI_rng_free(rng); - PE_update_selection(data.scene, data.scene_layer, data.ob, 1); + PE_update_selection(C, data.scene, data.scene_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1722,7 +1729,7 @@ static int select_linked_exec(bContext *C, wmOperator *op) data.select= !RNA_boolean_get(op->ptr, "deselect"); for_mouse_hit_keys(&data, select_keys, 1); /* nearest only */ - PE_update_selection(data.scene, data.scene_layer, data.ob, 1); + PE_update_selection(C, data.scene, data.scene_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1787,7 +1794,7 @@ int PE_border_select(bContext *C, rcti *rect, bool select, bool extend) for_mouse_hit_keys(&data, select_key, 0); - PE_update_selection(scene, sl, ob, 1); + PE_update_selection(C, scene, sl, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1813,7 +1820,7 @@ int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad) for_mouse_hit_keys(&data, select_key, 0); - PE_update_selection(scene, sl, ob, 1); + PE_update_selection(C, scene, sl, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1902,7 +1909,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool } } - PE_update_selection(scene, sl, ob, 1); + PE_update_selection(C, scene, sl, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1937,7 +1944,7 @@ static int hide_exec(bContext *C, wmOperator *op) } } - PE_update_selection(scene, sl, ob, 1); + PE_update_selection(C, scene, sl, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1981,7 +1988,7 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op)) } } - PE_update_selection(scene, sl, ob, 1); + PE_update_selection(C, scene, sl, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -2040,7 +2047,7 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op)) PE_set_data(C, &data); foreach_point(&data, select_less_keys); - PE_update_selection(data.scene, data.scene_layer, data.ob, 1); + PE_update_selection(C, data.scene, data.scene_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -2102,7 +2109,7 @@ static int select_more_exec(bContext *C, wmOperator *UNUSED(op)) PE_set_data(C, &data); foreach_point(&data, select_more_keys); - PE_update_selection(data.scene, data.scene_layer, data.ob, 1); + PE_update_selection(C, data.scene, data.scene_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -2135,12 +2142,15 @@ static void rekey_particle(PEData *data, int pa_index) ParticleKey state; HairKey *key, *new_keys, *okey; PTCacheEditKey *ekey; + EvaluationContext eval_ctx; float dval, sta, end; int k; - sim.scene= data->scene; - sim.ob= data->ob; - sim.psys= edit->psys; + CTX_data_eval_ctx(data->context, &eval_ctx); + sim.eval_ctx = &eval_ctx; + sim.scene = data->scene; + sim.ob = data->ob; + sim.psys = edit->psys; pa->flag |= PARS_REKEY; @@ -2199,7 +2209,7 @@ static int rekey_exec(bContext *C, wmOperator *op) foreach_selected_point(&data, rekey_particle); recalc_lengths(data.edit); - PE_update_object(data.scene, data.scene_layer, data.ob, 1); + PE_update_object(C, data.scene, data.scene_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob); return OPERATOR_FINISHED; @@ -2224,24 +2234,28 @@ void PARTICLE_OT_rekey(wmOperatorType *ot) RNA_def_int(ot->srna, "keys_number", 2, 2, INT_MAX, "Number of Keys", "", 2, 100); } -static void rekey_particle_to_time(Scene *scene, SceneLayer *sl, Object *ob, int pa_index, float path_time) +static void rekey_particle_to_time(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, int pa_index, float path_time) { PTCacheEdit *edit= PE_get_current(scene, sl, ob); ParticleSystem *psys; - ParticleSimulationData sim= {0}; + ParticleSimulationData sim = {0}; ParticleData *pa; ParticleKey state; HairKey *new_keys, *key; PTCacheEditKey *ekey; + EvaluationContext eval_ctx; int k; + CTX_data_eval_ctx(C, &eval_ctx); + if (!edit || !edit->psys) return; psys = edit->psys; - sim.scene= scene; - sim.ob= ob; - sim.psys= psys; + sim.eval_ctx = &eval_ctx; + sim.scene = scene; + sim.ob = ob; + sim.psys = psys; pa= psys->particles + pa_index; @@ -2451,14 +2465,17 @@ static void subdivide_particle(PEData *data, int pa_index) ParticleKey state; HairKey *key, *nkey, *new_keys; PTCacheEditKey *ekey, *nekey, *new_ekeys; + EvaluationContext eval_ctx; int k; short totnewkey=0; float endtime; - sim.scene= data->scene; - sim.ob= data->ob; - sim.psys= edit->psys; + CTX_data_eval_ctx(data->context, &eval_ctx); + sim.eval_ctx = &eval_ctx; + sim.scene = data->scene; + sim.ob = data->ob; + sim.psys = edit->psys; for (k=0, ekey=point->keys; k<pa->totkey-1; k++, ekey++) { if (ekey->flag&PEK_SELECT && (ekey+1)->flag&PEK_SELECT) @@ -2530,7 +2547,7 @@ static int subdivide_exec(bContext *C, wmOperator *UNUSED(op)) foreach_point(&data, subdivide_particle); recalc_lengths(data.edit); - PE_update_object(data.scene, data.scene_layer, data.ob, 1); + PE_update_object(C, data.scene, data.scene_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob); return OPERATOR_FINISHED; @@ -2813,7 +2830,7 @@ static void PE_mirror_x(Scene *scene, SceneLayer *sl, Object *ob, int tagged) { Mesh *me= (Mesh *)(ob->data); ParticleSystemModifierData *psmd; - PTCacheEdit *edit= PE_get_current(scene, sl, ob); + PTCacheEdit *edit = PE_get_current(scene, sl, ob); ParticleSystem *psys = edit->psys; ParticleData *pa, *newpa, *new_pars; PTCacheEditPoint *newpoint, *new_points; @@ -3101,7 +3118,7 @@ static void brush_cut(PEData *data, int pa_index) edit->points[pa_index].flag |= PEP_TAG; } else { - rekey_particle_to_time(data->scene, data->scene_layer, ob, pa_index, cut_time); + rekey_particle_to_time(data->context, data->scene, data->scene_layer, ob, pa_index, cut_time); edit->points[pa_index].flag |= PEP_EDIT_RECALC; } } @@ -3349,25 +3366,28 @@ static void intersect_dm_quad_weights(const float v1[3], const float v2[3], cons } /* check intersection with a derivedmesh */ -static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, +static int particle_intersect_dm(const bContext *C, Scene *scene, Object *ob, DerivedMesh *dm, float *vert_cos, const float co1[3], const float co2[3], float *min_d, int *min_face, float *min_w, float *face_minmax, float *pa_minmax, float radius, float *ipoint) { + EvaluationContext eval_ctx; MFace *mface= NULL; MVert *mvert= NULL; int i, totface, intersect=0; float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3], p_max[3]; float cur_ipoint[3]; + CTX_data_eval_ctx(C, &eval_ctx); + if (dm == NULL) { psys_disable_all(ob); - dm=mesh_get_derived_final(scene, ob, 0); + dm = mesh_get_derived_final(&eval_ctx, scene, ob, 0); if (dm == NULL) - dm=mesh_get_derived_deform(scene, ob, 0); + dm = mesh_get_derived_deform(&eval_ctx, scene, ob, 0); psys_enable_all(ob); @@ -3480,8 +3500,9 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, return intersect; } -static int brush_add(PEData *data, short number) +static int brush_add(const bContext *C, PEData *data, short number) { + EvaluationContext eval_ctx; Scene *scene= data->scene; Object *ob= data->ob; DerivedMesh *dm; @@ -3509,6 +3530,9 @@ static int brush_add(PEData *data, short number) rng = BLI_rng_new_srandom(psys->seed+data->mval[0]+data->mval[1]); + CTX_data_eval_ctx(C, &eval_ctx); + + sim.eval_ctx = &eval_ctx; sim.scene= scene; sim.ob= ob; sim.psys= psys; @@ -3549,7 +3573,7 @@ static int brush_add(PEData *data, short number) min_d=2.0; /* warning, returns the derived mesh face */ - if (particle_intersect_dm(scene, ob, dm, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) { + if (particle_intersect_dm(C, scene, ob, dm, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) { if (psys->part->use_modifier_stack && !psmd->dm_final->deformedOnly) { add_pars[n].num = add_pars[n].num_dmcache; add_pars[n].num_dmcache = DMCACHE_ISCHILD; @@ -3923,7 +3947,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) if (edit->psys && edit->psys->part->from==PART_FROM_FACE) { data.mval= mval; - added= brush_add(&data, brush->count); + added= brush_add(C, &data, brush->count); if (pset->flag & PE_KEEP_LENGTHS) recalc_lengths(edit); @@ -3980,7 +4004,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } else - PE_update_object(scene, sl, ob, 1); + PE_update_object(C, scene, sl, ob, 1); } if (edit->psys) { @@ -4193,7 +4217,7 @@ static void shape_cut(PEData *data, int pa_index) edit->points[pa_index].flag |= PEP_TAG; } else { - rekey_particle_to_time(data->scene, data->scene_layer, ob, pa_index, cut_time); + rekey_particle_to_time(data->context, data->scene, data->scene_layer, ob, pa_index, cut_time); edit->points[pa_index].flag |= PEP_EDIT_RECALC; } } @@ -4241,7 +4265,7 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op)) DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } else - PE_update_object(scene, sl, ob, 1); + PE_update_object(C, scene, sl, ob, 1); if (edit->psys) { WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); @@ -4603,7 +4627,7 @@ int PE_minmax(Scene *scene, SceneLayer *sl, float min[3], float max[3]) /************************ particle edit toggle operator ************************/ /* initialize needed data for bake edit */ -void PE_create_particle_edit(Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys) +void PE_create_particle_edit(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys) { PTCacheEdit *edit; ParticleSystemModifierData *psmd = (psys) ? psys_get_modifier(ob, psys) : NULL; @@ -4704,7 +4728,7 @@ void PE_create_particle_edit(Scene *scene, SceneLayer *sl, Object *ob, PointCach recalc_lengths(edit); if (psys && !cache) recalc_emitter_field(ob, psys); - PE_update_object(scene, sl, ob, 1); + PE_update_object(C, scene, sl, ob, 1); PTCacheUndo_clear(edit); PE_undo_push(scene, sl, "Original"); @@ -4746,7 +4770,7 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op) if (!is_mode_set) { PTCacheEdit *edit; ob->mode |= mode_flag; - edit= PE_create_current(scene, ob); + edit= PE_create_current(C, scene, ob); /* mesh may have changed since last entering editmode. * note, this may have run before if the edit data was just created, so could avoid this and speed up a little */ @@ -4922,7 +4946,7 @@ static int unify_length_exec(bContext *C, wmOperator *UNUSED(op)) } scale_points_to_length(edit, average_length); - PE_update_object(scene, sl, ob, 1); + PE_update_object(C, scene, sl, ob, 1); if (edit->psys) { WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); } diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index cd7bb8640b5..8a08be75421 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -71,7 +71,7 @@ #include "physics_intern.h" -extern void PE_create_particle_edit(Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys); +extern void PE_create_particle_edit(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys); extern void PTCacheUndo_clear(PTCacheEdit *edit); extern void recalc_lengths(PTCacheEdit *edit); extern void recalc_emitter_field(Object *ob, ParticleSystem *psys); @@ -568,7 +568,7 @@ void PARTICLE_OT_dupliob_move_down(wmOperatorType *ot) /************************ connect/disconnect hair operators *********************/ -static void disconnect_hair(Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys) +static void disconnect_hair(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys) { ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); ParticleEditSettings *pset= PE_settings(scene); @@ -614,7 +614,7 @@ static void disconnect_hair(Scene *scene, SceneLayer *sl, Object *ob, ParticleSy if (ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_PUFF)) pset->brushtype = PE_BRUSH_NONE; - PE_update_object(scene, sl, ob, 0); + PE_update_object(C, scene, sl, ob, 0); } static int disconnect_hair_exec(bContext *C, wmOperator *op) @@ -630,12 +630,12 @@ static int disconnect_hair_exec(bContext *C, wmOperator *op) if (all) { for (psys=ob->particlesystem.first; psys; psys=psys->next) { - disconnect_hair(scene, sl, ob, psys); + disconnect_hair(C, scene, sl, ob, psys); } } else { psys = psys_get_current(ob); - disconnect_hair(scene, sl, ob, psys); + disconnect_hair(C, scene, sl, ob, psys); } DEG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -661,7 +661,7 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot) /* from/to_world_space : whether from/to particles are in world or hair space * from/to_mat : additional transform for from/to particles (e.g. for using object space copying) */ -static bool remap_hair_emitter(Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys, +static bool remap_hair_emitter(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys, Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit, float from_mat[4][4], float to_mat[4][4], bool from_global, bool to_global) { @@ -847,19 +847,19 @@ static bool remap_hair_emitter(Scene *scene, SceneLayer *sl, Object *ob, Particl psys_free_path_cache(target_psys, target_edit); - PE_update_object(scene, sl, target_ob, 0); + PE_update_object(C, scene, sl, target_ob, 0); return true; } -static bool connect_hair(Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys) +static bool connect_hair(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys) { bool ok; if (!psys) return false; - ok = remap_hair_emitter(scene, sl, ob, psys, ob, psys, psys->edit, ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false); + ok = remap_hair_emitter(C, scene, sl, ob, psys, ob, psys, psys->edit, ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false); psys->flag &= ~PSYS_GLOBAL_HAIR; return ok; @@ -879,12 +879,12 @@ static int connect_hair_exec(bContext *C, wmOperator *op) if (all) { for (psys=ob->particlesystem.first; psys; psys=psys->next) { - any_connected |= connect_hair(scene, sl, ob, psys); + any_connected |= connect_hair(C, scene, sl, ob, psys); } } else { psys = psys_get_current(ob); - any_connected |= connect_hair(scene, sl, ob, psys); + any_connected |= connect_hair(C, scene, sl, ob, psys); } if (!any_connected) { @@ -920,7 +920,7 @@ typedef enum eCopyParticlesSpace { PAR_COPY_SPACE_WORLD = 1, } eCopyParticlesSpace; -static void copy_particle_edit(Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys, ParticleSystem *psys_from) +static void copy_particle_edit(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys, ParticleSystem *psys_from) { PTCacheEdit *edit_from = psys_from->edit, *edit; ParticleData *pa; @@ -970,7 +970,7 @@ static void copy_particle_edit(Scene *scene, SceneLayer *sl, Object *ob, Particl recalc_lengths(edit); recalc_emitter_field(ob, psys); - PE_update_object(scene, sl, ob, true); + PE_update_object(C, scene, sl, ob, true); PTCacheUndo_clear(edit); PE_undo_push(scene, sl, "Original"); @@ -1001,7 +1001,7 @@ static void remove_particle_systems_from_object(Object *ob_to) } /* single_psys_from is optional, if NULL all psys of ob_from are copied */ -static bool copy_particle_systems_to_object(Main *bmain, +static bool copy_particle_systems_to_object(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob_from, @@ -1010,6 +1010,8 @@ static bool copy_particle_systems_to_object(Main *bmain, int space, bool duplicate_settings) { + Main *bmain = CTX_data_main(C); + EvaluationContext eval_ctx; ModifierData *md; ParticleSystem *psys_start = NULL, *psys, *psys_from; ParticleSystem **tmp_psys; @@ -1017,6 +1019,8 @@ static bool copy_particle_systems_to_object(Main *bmain, CustomDataMask cdmask; int i, totpsys; + CTX_data_eval_ctx(C, &eval_ctx); + if (ob_to->type != OB_MESH) return false; if (!ob_to->data || ID_IS_LINKED_DATABLOCK(ob_to->data)) @@ -1055,7 +1059,7 @@ static bool copy_particle_systems_to_object(Main *bmain, psys_start = totpsys > 0 ? tmp_psys[0] : NULL; /* get the DM (psys and their modifiers have not been appended yet) */ - final_dm = mesh_get_derived_final(scene, ob_to, cdmask); + final_dm = mesh_get_derived_final(&eval_ctx, scene, ob_to, cdmask); /* now append psys to the object and make modifiers */ for (i = 0, psys_from = PSYS_FROM_FIRST; @@ -1084,7 +1088,7 @@ static bool copy_particle_systems_to_object(Main *bmain, DM_ensure_tessface(psmd->dm_final); if (psys_from->edit) - copy_particle_edit(scene, sl, ob_to, psys, psys_from); + copy_particle_edit(C, scene, sl, ob_to, psys, psys_from); if (duplicate_settings) { id_us_min(&psys->part->id); @@ -1118,7 +1122,7 @@ static bool copy_particle_systems_to_object(Main *bmain, break; } if (ob_from != ob_to) { - remap_hair_emitter(scene, sl, ob_from, psys_from, ob_to, psys, psys->edit, from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR); + remap_hair_emitter(C, scene, sl, ob_from, psys_from, ob_to, psys, psys->edit, from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR); } /* tag for recalc */ @@ -1151,7 +1155,6 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op) const int space = RNA_enum_get(op->ptr, "space"); const bool remove_target_particles = RNA_boolean_get(op->ptr, "remove_target_particles"); const bool use_active = RNA_boolean_get(op->ptr, "use_active"); - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); SceneLayer *sl = CTX_data_scene_layer(C); Object *ob_from = ED_object_active_context(C); @@ -1168,7 +1171,7 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op) remove_particle_systems_from_object(ob_to); changed = true; } - if (copy_particle_systems_to_object(bmain, scene, sl, ob_from, psys_from, ob_to, space, false)) + if (copy_particle_systems_to_object(C, scene, sl, ob_from, psys_from, ob_to, space, false)) changed = true; else fail++; @@ -1229,7 +1232,7 @@ static int duplicate_particle_systems_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data; - copy_particle_systems_to_object(CTX_data_main(C), scene, CTX_data_scene_layer(C), ob, psys, ob, + copy_particle_systems_to_object(C, scene, CTX_data_scene_layer(C), ob, psys, ob, PAR_COPY_SPACE_OBJECT, duplicate_settings); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index 6e62dbabbca..9cd571c68cf 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -55,6 +55,8 @@ #include "BKE_report.h" #include "BKE_scene.h" +#include "DEG_depsgraph.h" + #include "LBM_fluidsim.h" #include "ED_screen.h" @@ -244,7 +246,7 @@ static void set_channel(float *channel, float time, float *value, int i, int siz } } -static void set_vertex_channel(float *channel, float time, struct Scene *scene, struct FluidObject *fobj, int i) +static void set_vertex_channel(EvaluationContext *eval_ctx, float *channel, float time, struct Scene *scene, struct FluidObject *fobj, int i) { Object *ob = fobj->object; FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); @@ -257,7 +259,7 @@ static void set_vertex_channel(float *channel, float time, struct Scene *scene, if (channel == NULL) return; - initElbeemMesh(scene, ob, &numVerts, &verts, &numTris, &tris, 1, modifierIndex); + initElbeemMesh(eval_ctx, scene, ob, &numVerts, &verts, &numTris, &tris, 1, modifierIndex); /* don't allow mesh to change number of verts in anim sequence */ if (numVerts != fobj->numVerts) { @@ -330,10 +332,13 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid { Scene *scene = CTX_data_scene(C); SceneLayer *sl = CTX_data_scene_layer(C); + EvaluationContext eval_ctx; Base *base; int i; int length = channels->length; float eval_time; + + CTX_data_eval_ctx(C, &eval_ctx); /* init time values (assuming that time moves at a constant speed; may be overridden later) */ init_time(domainSettings, channels); @@ -374,7 +379,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid float *verts=NULL; int *tris=NULL, modifierIndex = BLI_findindex(&ob->modifiers, (ModifierData *)fluidmd); - initElbeemMesh(scene, ob, &fobj->numVerts, &verts, &fobj->numTris, &tris, 0, modifierIndex); + initElbeemMesh(&eval_ctx, scene, ob, &fobj->numVerts, &verts, &fobj->numTris, &tris, 0, modifierIndex); fobj->VertexCache = MEM_callocN(length *((fobj->numVerts*CHANNEL_VEC)+1) * sizeof(float), "fluidobject VertexCache"); MEM_freeN(verts); @@ -462,15 +467,18 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid } if (fluid_is_animated_mesh(fluidmd->fss)) { - set_vertex_channel(fobj->VertexCache, timeAtFrame, scene, fobj, i); + set_vertex_channel(&eval_ctx, fobj->VertexCache, timeAtFrame, scene, fobj, i); } } } } -static void export_fluid_objects(ListBase *fobjects, Scene *scene, int length) +static void export_fluid_objects(const bContext *C, ListBase *fobjects, Scene *scene, int length) { FluidObject *fobj; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); for (fobj=fobjects->first; fobj; fobj=fobj->next) { Object *ob = fobj->object; @@ -492,7 +500,7 @@ static void export_fluid_objects(ListBase *fobjects, Scene *scene, int length) fsmesh.type = fluidmd->fss->type; fsmesh.name = ob->id.name; - initElbeemMesh(scene, ob, &numVerts, &verts, &numTris, &tris, 0, modifierIndex); + initElbeemMesh(&eval_ctx, scene, ob, &numVerts, &verts, &numTris, &tris, 0, modifierIndex); fsmesh.numVertices = numVerts; fsmesh.numTriangles = numTris; @@ -1036,7 +1044,7 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor elbeemAddDomain(fsset); /* ******** export all fluid objects to elbeem ******** */ - export_fluid_objects(fobjects, scene, channels->length); + export_fluid_objects(C, fobjects, scene, channels->length); /* custom data for fluid bake job */ fb->settings = fsset; diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 193fac63050..f3987b8eb39 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -1241,7 +1241,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda use_border = render_view3d_disprect(rp->scene, rp->ar, rp->v3d, rp->rv3d, &cliprct); - if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE)) || rstats->convertdone == 0) { + if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE | PR_UPDATE_VIEW)) || rstats->convertdone == 0) { RenderData rdata; /* no osa, blur, seq, layers, savebuffer etc for preview render */ diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 65b0eb2b005..adb58ac6c92 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -55,6 +55,8 @@ #include "BKE_sequencer.h" #include "BKE_writeavi.h" +#include "DEG_depsgraph.h" + #include "WM_api.h" #include "WM_types.h" @@ -261,7 +263,7 @@ static void screen_opengl_views_setup(OGLRender *oglrender) RE_ReleaseResult(oglrender->re); } -static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr) +static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, RenderResult *rr) { Scene *scene = oglrender->scene; SceneLayer *sl = oglrender->scene_layer; @@ -277,6 +279,9 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr) unsigned char *rect = NULL; const char *viewname = RE_GetActiveRenderView(oglrender->re); ImBuf *ibuf_result = NULL; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); if (oglrender->is_sequencer) { SpaceSeq *sseq = oglrender->sseq; @@ -346,7 +351,7 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr) if (view_context) { ibuf_view = ED_view3d_draw_offscreen_imbuf( - scene, sl, v3d, ar, sizex, sizey, + &eval_ctx, scene, sl, v3d, ar, sizex, sizey, IB_rect, draw_bgpic, alpha_mode, oglrender->ofs_samples, oglrender->ofs_full_samples, viewname, oglrender->fx, oglrender->ofs, err_out); @@ -358,7 +363,7 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr) } else { ibuf_view = ED_view3d_draw_offscreen_imbuf_simple( - scene, sl, scene->camera, oglrender->sizex, oglrender->sizey, + &eval_ctx, scene, sl, scene->camera, oglrender->sizex, oglrender->sizey, IB_rect, OB_SOLID, false, true, true, alpha_mode, oglrender->ofs_samples, oglrender->ofs_full_samples, viewname, oglrender->fx, oglrender->ofs, err_out); @@ -421,7 +426,7 @@ static void addAlphaOverFloat(float dest[4], const float source[4]) } /* add renderlayer and renderpass for each grease pencil layer for using in composition */ -static void add_gpencil_renderpass(OGLRender *oglrender, RenderResult *rr, RenderView *rv) +static void add_gpencil_renderpass(const bContext *C, OGLRender *oglrender, RenderResult *rr, RenderView *rv) { bGPdata *gpd = oglrender->scene->gpd; Scene *scene = oglrender->scene; @@ -465,7 +470,7 @@ static void add_gpencil_renderpass(OGLRender *oglrender, RenderResult *rr, Rende } /* render this gp layer */ - screen_opengl_render_doit(oglrender, rr); + screen_opengl_render_doit(C, oglrender, rr); /* add RendePass composite */ RenderPass *rp = RE_create_gp_pass(rr, gpl->info, rv->name); @@ -505,7 +510,7 @@ static void add_gpencil_renderpass(OGLRender *oglrender, RenderResult *rr, Rende scene->r.alphamode = oldalphamode; } -static void screen_opengl_render_apply(OGLRender *oglrender) +static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender) { RenderResult *rr; RenderView *rv; @@ -543,10 +548,10 @@ static void screen_opengl_render_apply(OGLRender *oglrender) /* add grease pencil passes. For sequencer, the render does not include renderpasses * TODO: The sequencer render of grease pencil should be rethought */ if (!oglrender->is_sequencer) { - add_gpencil_renderpass(oglrender, rr, rv); + add_gpencil_renderpass(C, oglrender, rr, rv); } /* render composite */ - screen_opengl_render_doit(oglrender, rr); + screen_opengl_render_doit(C, oglrender, rr); } RE_ReleaseResult(oglrender->re); @@ -1048,7 +1053,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op) } /* render into offscreen buffer */ - screen_opengl_render_apply(oglrender); + screen_opengl_render_apply(C, oglrender); /* save to disk */ rr = RE_AcquireResultRead(oglrender->re); @@ -1098,7 +1103,7 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); if (anim == 0) { - screen_opengl_render_apply(op->customdata); + screen_opengl_render_apply(C, op->customdata); screen_opengl_render_end(C, op->customdata); return OPERATOR_FINISHED; } @@ -1149,7 +1154,7 @@ static int screen_opengl_render_exec(bContext *C, wmOperator *op) if (!is_animation) { /* same as invoke */ /* render image */ - screen_opengl_render_apply(op->customdata); + screen_opengl_render_apply(C, op->customdata); screen_opengl_render_end(C, op->customdata); return OPERATOR_FINISHED; diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 1a3d1ce083e..a9a469b4e46 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -318,6 +318,19 @@ static void set_preview_layer(SceneLayer *scene_layer, char pr_type) } } +static World *preview_get_localized_world(ShaderPreview *sp, World *world) +{ + if (world == NULL) { + return NULL; + } + if (sp->worldcopy != NULL) { + return sp->worldcopy; + } + sp->worldcopy = localize_world(world); + BLI_addtail(&sp->pr_main->world, sp->worldcopy); + return sp->worldcopy; +} + /* call this with a pointer to initialize preview scene */ /* call this with NULL to restore assigned ID pointers in preview scene */ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_type, ShaderPreview *sp) @@ -439,8 +452,9 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty } else { /* use current scene world to light sphere */ - if (mat->pr_type == MA_SPHERE_A) - sce->world = scene->world; + if (mat->pr_type == MA_SPHERE_A) { + sce->world = preview_get_localized_world(sp, scene->world); + } } if (sp->pr_method == PR_ICON_RENDER) { @@ -452,7 +466,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty /* same as above, use current scene world to light sphere */ if (BKE_scene_use_new_shading_nodes(scene)) - sce->world = scene->world; + sce->world = preview_get_localized_world(sp, scene->world); } } else { @@ -541,7 +555,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty if (!BKE_scene_use_new_shading_nodes(scene)) { if (la && la->type == LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) { set_preview_layer(scene_layer, MA_ATMOS); - sce->world = scene->world; + sce->world = preview_get_localized_world(sp, scene->world); sce->camera = (Object *)BLI_findstring(&pr_main->object, "CameraAtmo", offsetof(ID, name) + 2); } else { diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 2cdd49b3113..5071c5db4ea 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -656,7 +656,7 @@ static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene); + SceneLayer *sl = CTX_data_scene_layer(C); if (!ED_scene_render_layer_delete(bmain, scene, sl, NULL)) { return OPERATOR_CANCELLED; @@ -1822,7 +1822,7 @@ static void paste_mtex_copybuf(ID *id) mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]); break; default: - BLI_assert("invalid id type"); + BLI_assert(!"invalid id type"); return; } diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 42d914b1a71..3a9d11be3fd 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -299,8 +299,11 @@ static void material_changed(Main *bmain, Material *ma) BKE_icon_changed(BKE_icon_id_ensure(&ma->id)); /* glsl */ - if (ma->gpumaterial.first) - GPU_material_free(&ma->gpumaterial); + if (ma->id.tag & LIB_TAG_ID_RECALC) { + if (!BLI_listbase_is_empty(&ma->gpumaterial)) { + GPU_material_free(&ma->gpumaterial); + } + } /* find node materials using this */ for (parent = bmain->mat.first; parent; parent = parent->id.next) { @@ -478,13 +481,16 @@ static void world_changed(Main *UNUSED(bmain), World *wo) /* XXX temporary flag waiting for depsgraph proper tagging */ wo->update_flag = 1; - + /* glsl */ - if (defmaterial.gpumaterial.first) - GPU_material_free(&defmaterial.gpumaterial); - - if (wo->gpumaterial.first) - GPU_material_free(&wo->gpumaterial); + if (wo->id.tag & LIB_TAG_ID_RECALC) { + if (!BLI_listbase_is_empty(&defmaterial.gpumaterial)) { + GPU_material_free(&defmaterial.gpumaterial); + } + if (!BLI_listbase_is_empty(&wo->gpumaterial)) { + GPU_material_free(&wo->gpumaterial); + } + } } static void image_changed(Main *bmain, Image *ima) diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 3e4b4b501ce..d762419b550 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -856,8 +856,10 @@ static void region_cursor_set(wmWindow *win, int swinid, int swin_changed) for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid == swinid) { if (swin_changed || (ar->type && ar->type->event_cursor)) { - if (WM_manipulatormap_cursor_set(ar->manipulator_map, win)) { - return; + if (ar->manipulator_map != NULL) { + if (WM_manipulatormap_cursor_set(ar->manipulator_map, win)) { + return; + } } ED_region_cursor_set(win, sa, ar); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index b8fa16117a9..326421cf166 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2274,25 +2274,28 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) BLI_dlrbTree_linkedlist_sync(&keys); /* find matching keyframe in the right direction */ - do { - if (next) - ak = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfra); - else - ak = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfra); - - if (ak) { - if (CFRA != (int)ak->cfra) { - /* this changes the frame, so set the frame and we're done */ - CFRA = (int)ak->cfra; - done = true; + if (next) + ak = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfra); + else + ak = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfra); + + while ((ak != NULL) && (done == false)) { + if (CFRA != (int)ak->cfra) { + /* this changes the frame, so set the frame and we're done */ + CFRA = (int)ak->cfra; + done = true; + } + else { + /* take another step... */ + if (next) { + ak = ak->next; } else { - /* make this the new starting point for the search */ - cfra = ak->cfra; + ak = ak->prev; } } - } while ((ak != NULL) && (done == false)); - + } + /* free temp stuff */ BLI_dlrbTree_free(&keys); diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index d7c3b7377da..d2e2df01238 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -52,6 +52,8 @@ #include "BKE_paint.h" #include "BKE_subsurf.h" +#include "DEG_depsgraph.h" + #include "WM_api.h" #include "WM_types.h" @@ -360,6 +362,7 @@ static int hide_show_exec(bContext *C, wmOperator *op) { ARegion *ar = CTX_wm_region(C); Object *ob = CTX_data_active_object(C); + EvaluationContext eval_ctx; Mesh *me = ob->data; PartialVisAction action; PartialVisArea area; @@ -371,6 +374,8 @@ static int hide_show_exec(bContext *C, wmOperator *op) rcti rect; int totnode, i; + CTX_data_eval_ctx(C, &eval_ctx); + /* read operator properties */ action = RNA_enum_get(op->ptr, "action"); area = RNA_enum_get(op->ptr, "area"); @@ -378,7 +383,7 @@ static int hide_show_exec(bContext *C, wmOperator *op) clip_planes_from_rect(C, clip_planes, &rect); - dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); + dm = mesh_get_derived_final(&eval_ctx, CTX_data_scene(C), ob, CD_MASK_BAREMESH); pbvh = dm->getPBVH(ob, dm); ob->sculpt->pbvh = pbvh; diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c index eb6eebf3c54..30830e4e7bc 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.c +++ b/source/blender/editors/sculpt_paint/paint_image_2d.c @@ -798,6 +798,7 @@ static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const bool is_torus float map_alpha = (rgb[3] == 0.0f) ? rrgbf[3] : rrgbf[3] / rgb[3]; mul_v3_v3fl(rrgbf, rgb, map_alpha); + rrgbf[3] = rgb[3]; } else { unsigned char straight[4]; @@ -807,6 +808,7 @@ static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const bool is_torus rrgb[0] = straight[0]; rrgb[1] = straight[1]; rrgb[2] = straight[2]; + rrgb[3] = straight[3]; } } @@ -996,7 +998,7 @@ static void paint_2d_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos, short tile) IMB_rectblend(ibufb, ibufb, ibuf, NULL, NULL, NULL, 0, region[a].destx, region[a].desty, region[a].destx, region[a].desty, region[a].srcx, region[a].srcy, - region[a].width, region[a].height, IMB_BLEND_COPY_RGB, false); + region[a].width, region[a].height, IMB_BLEND_COPY, false); } static ImBuf *paint_2d_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos) @@ -1097,6 +1099,7 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsign /* lift from canvas */ if (s->tool == PAINT_TOOL_SOFTEN) { paint_2d_lift_soften(s, s->canvas, ibufb, bpos, tile); + blend = IMB_BLEND_INTERPOLATE; } else if (s->tool == PAINT_TOOL_SMEAR) { if (lastpos[0] == pos[0] && lastpos[1] == pos[1]) @@ -1104,6 +1107,7 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsign paint_2d_convert_brushco(ibufb, lastpos, blastpos); paint_2d_lift_smear(s->canvas, ibufb, blastpos, tile); + blend = IMB_BLEND_INTERPOLATE; } else if (s->tool == PAINT_TOOL_CLONE && s->clonecanvas) { liftpos[0] = pos[0] - offset[0] * s->canvas->x; diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index eeb357d43e7..65f4618e43e 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -3421,12 +3421,15 @@ static void project_paint_bleed_add_face_user( #endif /* Return true if DM can be painted on, false otherwise */ -static bool proj_paint_state_dm_init(ProjPaintState *ps) +static bool proj_paint_state_dm_init(const bContext *C, ProjPaintState *ps) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + /* Workaround for subsurf selection, try the display mesh first */ if (ps->source == PROJ_SRC_IMAGE_CAM) { /* using render mesh, assume only camera was rendered from */ - ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE); + ps->dm = mesh_create_derived_render(&eval_ctx, ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE); ps->dm_release = true; } else if (ps->ob->derivedFinal && @@ -3438,7 +3441,7 @@ static bool proj_paint_state_dm_init(ProjPaintState *ps) } else { ps->dm = mesh_get_derived_final( - ps->scene, ps->ob, + &eval_ctx, ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE | (ps->do_face_sel ? CD_ORIGINDEX : 0)); ps->dm_release = true; } @@ -3818,7 +3821,7 @@ static void project_paint_prepare_all_faces( /* run once per stroke before projection painting */ static void project_paint_begin( - ProjPaintState *ps, + const bContext *C, ProjPaintState *ps, const bool is_multi_view, const char symmetry_flag) { ProjPaintLayerClone layer_clone; @@ -3841,7 +3844,7 @@ static void project_paint_begin( /* paint onto the derived mesh */ if (ps->is_shared_user == false) { - if (!proj_paint_state_dm_init(ps)) { + if (!proj_paint_state_dm_init(C, ps)) { return; } } @@ -4296,7 +4299,7 @@ static void do_projectpaint_soften_f(ProjPaintState *ps, ProjPixel *projPixel, f return; } else { - blend_color_interpolate_float(rgba, rgba, projPixel->pixel.f_pt, mask); + blend_color_interpolate_float(rgba, projPixel->pixel.f_pt, rgba, mask); } BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena); @@ -4755,6 +4758,9 @@ static void *do_projectpaint_thread(void *ph_v) copy_v3_v3(texrgb, texrgba); mask *= texrgba[3]; } + else { + zero_v3(texrgb); + } /* extra mask for normal, layer stencil, .. */ mask *= ((float)projPixel->mask) * (1.0f / 65535.0f); @@ -5030,7 +5036,7 @@ void paint_proj_stroke( view3d_operator_needs_opengl(C); - if (!ED_view3d_autodist(graph, ar, v3d, mval_i, cursor, false, NULL)) { + if (!ED_view3d_autodist(C, graph, ar, v3d, mval_i, cursor, false, NULL)) { return; } @@ -5234,7 +5240,7 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m PROJ_PAINT_STATE_SHARED_MEMCPY(ps, ps_handle->ps_views[0]); } - project_paint_begin(ps, is_multi_view, symmetry_flag_views[i]); + project_paint_begin(C, ps, is_multi_view, symmetry_flag_views[i]); paint_proj_begin_clone(ps, mouse); @@ -5388,7 +5394,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) ED_image_undo_restore, ED_image_undo_free, NULL); /* allocate and initialize spatial data structures */ - project_paint_begin(&ps, false, 0); + project_paint_begin(C, &ps, false, 0); if (ps.dm == NULL) { BKE_brush_size_set(scene, ps.brush, orig_brush_size); @@ -5447,12 +5453,15 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); SceneLayer *sl = CTX_data_scene_layer(C); + EvaluationContext eval_ctx; ToolSettings *settings = scene->toolsettings; int w = settings->imapaint.screen_grab_size[0]; int h = settings->imapaint.screen_grab_size[1]; int maxsize; char err_out[256] = "unknown"; + CTX_data_eval_ctx(C, &eval_ctx); + RNA_string_get(op->ptr, "filepath", filename); maxsize = GPU_max_texture_size(); @@ -5461,7 +5470,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (h > maxsize) h = maxsize; ibuf = ED_view3d_draw_offscreen_imbuf( - scene, sl, CTX_wm_view3d(C), CTX_wm_region(C), + &eval_ctx, scene, sl, CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, false, R_ALPHAPREMUL, 0, false, NULL, NULL, NULL, err_out); if (!ibuf) { diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 69c4621945b..2915f17d9fc 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -127,10 +127,10 @@ unsigned int vpaint_get_current_col(struct Scene *scene, struct VPaint *vp); /* paint_vertex_proj.c */ struct VertProjHandle; struct VertProjHandle *ED_vpaint_proj_handle_create( - struct Scene *scene, struct Object *ob, + const struct bContext *C, struct Scene *scene, struct Object *ob, struct DMCoNo **r_vcosnos); void ED_vpaint_proj_handle_update( - struct VertProjHandle *vp_handle, + const struct bContext *C, struct VertProjHandle *vp_handle, /* runtime vars */ struct ARegion *ar, const float mval_fl[2]); void ED_vpaint_proj_handle_free( diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 1ac40b0354e..b7159c375cd 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -50,6 +50,8 @@ #include "BKE_paint.h" #include "BKE_subsurf.h" +#include "DEG_depsgraph.h" + #include "RNA_access.h" #include "RNA_define.h" @@ -129,6 +131,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) ARegion *ar = CTX_wm_region(C); struct Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + EvaluationContext eval_ctx; PaintMaskFloodMode mode; float value; PBVH *pbvh; @@ -137,10 +140,12 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) bool multires; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; + CTX_data_eval_ctx(C, &eval_ctx); + mode = RNA_enum_get(op->ptr, "mode"); value = RNA_float_get(op->ptr, "value"); - BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true); + BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, false, true); pbvh = ob->sculpt->pbvh; multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS); @@ -247,6 +252,7 @@ static void mask_box_select_task_cb(void *userdata, const int i) int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *rect, bool select, bool UNUSED(extend)) { + EvaluationContext eval_ctx; Sculpt *sd = vc->scene->toolsettings->sculpt; BoundBox bb; float clip_planes[4][4]; @@ -262,6 +268,8 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r int totnode, symmpass; int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; + CTX_data_eval_ctx(C, &eval_ctx); + mode = PAINT_MASK_FLOOD_VALUE; value = select ? 1.0 : 0.0; @@ -269,7 +277,7 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r ED_view3d_clipping_calc(&bb, clip_planes, vc->ar, vc->obact, rect); negate_m4(clip_planes); - BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true); + BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, false, true); pbvh = ob->sculpt->pbvh; multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS); @@ -405,6 +413,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); if (mcords) { + EvaluationContext eval_ctx; float clip_planes[4][4], clip_planes_final[4][4]; BoundBox bb; Object *ob; @@ -420,6 +429,8 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) PaintMaskFloodMode mode = RNA_enum_get(op->ptr, "mode"); float value = RNA_float_get(op->ptr, "value"); + CTX_data_eval_ctx(C, &eval_ctx); + /* Calculations of individual vertices are done in 2D screen space to diminish the amount of * calculations done. Bounding box PBVH collision is not computed against enclosing rectangle * of lasso */ @@ -442,7 +453,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) ED_view3d_clipping_calc(&bb, clip_planes, vc.ar, vc.obact, &data.rect); negate_m4(clip_planes); - BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true); + BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, false, true); pbvh = ob->sculpt->pbvh; multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS); diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 1ff6dd4813f..9d571fc12fe 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -851,8 +851,6 @@ static int brush_uv_sculpt_tool_set_exec(bContext *C, wmOperator *op) static void BRUSH_OT_uv_sculpt_tool_set(wmOperatorType *ot) { - /* from rna_scene.c */ - extern EnumPropertyItem uv_sculpt_tool_items[]; /* identifiers */ ot->name = "UV Sculpt Tool Set"; ot->description = "Set the UV sculpt tool"; @@ -866,7 +864,7 @@ static void BRUSH_OT_uv_sculpt_tool_set(wmOperatorType *ot) ot->flag = 0; /* props */ - ot->prop = RNA_def_enum(ot->srna, "tool", uv_sculpt_tool_items, 0, "Tool", ""); + ot->prop = RNA_def_enum(ot->srna, "tool", rna_enum_uv_sculpt_tool_items, 0, "Tool", ""); } /***** Stencil Control *****/ diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index e36cc275ba9..f8c8d8fb41e 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -56,6 +56,8 @@ #include "BKE_paint.h" #include "BKE_report.h" +#include "DEG_depsgraph.h" + #include "RNA_access.h" #include "RNA_define.h" @@ -268,9 +270,9 @@ static void imapaint_tri_weights(float matrix[4][4], GLint view[4], } /* compute uv coordinates of mouse in face */ -static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, const int xy[2], float uv[2]) +static void imapaint_pick_uv(EvaluationContext *eval_ctx, Scene *scene, Object *ob, unsigned int faceindex, const int xy[2], float uv[2]) { - DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH); const int tottri = dm->getNumLoopTri(dm); int i, findex; float p[2], w[3], absw, minabsw; @@ -346,13 +348,13 @@ static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, c } /* returns 0 if not found, otherwise 1 */ -static int imapaint_pick_face(ViewContext *vc, const int mval[2], unsigned int *r_index, unsigned int totpoly) +static int imapaint_pick_face(const bContext *C, ViewContext *vc, const int mval[2], unsigned int *r_index, unsigned int totpoly) { if (totpoly == 0) return 0; /* sample only on the exact position */ - *r_index = ED_view3d_backbuf_sample(vc, mval[0], mval[1]); + *r_index = ED_view3d_backbuf_sample(C, vc, mval[0], mval[1]); if ((*r_index) == 0 || (*r_index) > (unsigned int)totpoly) { return 0; @@ -418,13 +420,16 @@ void flip_qt_qt(float out[4], const float in[4], const char symm) void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_proj, bool use_palette) { Scene *scene = CTX_data_scene(C); + EvaluationContext eval_ctx; Paint *paint = BKE_paint_get_active_from_context(C); Palette *palette = BKE_paint_palette(paint); - PaletteColor *color; + PaletteColor *color = NULL; Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C)); unsigned int col; const unsigned char *cp; + CTX_data_eval_ctx(C, &eval_ctx); + CLAMP(x, 0, ar->winx); CLAMP(y, 0, ar->winy); @@ -449,7 +454,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr if (ob) { Mesh *me = (Mesh *)ob->data; - DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + DerivedMesh *dm = mesh_get_derived_final(&eval_ctx, scene, ob, CD_MASK_BAREMESH); ViewContext vc; const int mval[2] = {x, y}; @@ -461,7 +466,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr view3d_operator_needs_opengl(C); - if (imapaint_pick_face(&vc, mval, &faceindex, totpoly)) { + if (imapaint_pick_face(C, &vc, mval, &faceindex, totpoly)) { Image *image; if (use_material) @@ -474,7 +479,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr if (ibuf && ibuf->rect) { float uv[2]; float u, v; - imapaint_pick_uv(scene, ob, faceindex, mval, uv); + imapaint_pick_uv(&eval_ctx, scene, ob, faceindex, mval, uv); sample_success = true; u = fmodf(uv[0], 1.0f); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 46d71ad0c45..b395ac5c49d 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -814,7 +814,7 @@ static unsigned int vpaint_blend(VPaint *vp, unsigned int col, unsigned int colo } -static int sample_backbuf_area(ViewContext *vc, int *indexar, int totpoly, int x, int y, float size) +static int sample_backbuf_area(const bContext *C, ViewContext *vc, int *indexar, int totpoly, int x, int y, float size) { struct ImBuf *ibuf; int a, tot = 0, index; @@ -823,7 +823,7 @@ static int sample_backbuf_area(ViewContext *vc, int *indexar, int totpoly, int x * brushes with size > 64, why is this here? */ /*if (size > 64.0) size = 64.0;*/ - ibuf = ED_view3d_backbuf_read(vc, x - size, y - size, x + size, y + size); + ibuf = ED_view3d_backbuf_read(C, vc, x - size, y - size, x + size, y + size); if (ibuf) { unsigned int *rt = ibuf->rect; @@ -2097,7 +2097,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UN } /* painting on subsurfs should give correct points too, this returns me->totvert amount */ - wpd->vp_handle = ED_vpaint_proj_handle_create(scene, ob, &wpd->vertexcosnos); + wpd->vp_handle = ED_vpaint_proj_handle_create(C, scene, ob, &wpd->vertexcosnos); wpd->indexar = get_indexarray(me); copy_wpaint_prev(wp, me->dvert, me->totvert); @@ -2243,7 +2243,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P /* Ugly x2, we need this so hidden faces don't draw */ me->editflag |= ME_EDIT_PAINT_FACE_SEL; } - totindex = sample_backbuf_area(vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure); + totindex = sample_backbuf_area(C, vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure); me->editflag = editflag_prev; if (use_face_sel && me->totpoly) { @@ -2264,7 +2264,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P } /* incase we have modifiers */ - ED_vpaint_proj_handle_update(wpd->vp_handle, vc->ar, mval); + ED_vpaint_proj_handle_update(C, wpd->vp_handle, vc->ar, mval); /* make sure each vertex gets treated only once */ /* and calculate filter weight */ @@ -2693,7 +2693,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f paint_stroke_set_mode_data(stroke, vpd); view3d_set_viewcontext(C, &vpd->vc); - vpd->vp_handle = ED_vpaint_proj_handle_create(vpd->vc.scene, ob, &vpd->vertexcosnos); + vpd->vp_handle = ED_vpaint_proj_handle_create(C, vpd->vc.scene, ob, &vpd->vertexcosnos); vpd->indexar = get_indexarray(me); vpd->paintcol = vpaint_get_current_col(scene, vp); @@ -2827,7 +2827,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P mul_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat); /* which faces are involved */ - totindex = sample_backbuf_area(vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure); + totindex = sample_backbuf_area(C, vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure); if ((me->editflag & ME_EDIT_PAINT_FACE_SEL) && me->mpoly) { for (index = 0; index < totindex; index++) { @@ -2843,7 +2843,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P swap_m4m4(vc->rv3d->persmat, mat); /* incase we have modifiers */ - ED_vpaint_proj_handle_update(vpd->vp_handle, vc->ar, mval); + ED_vpaint_proj_handle_update(C, vpd->vp_handle, vc->ar, mval); /* clear modified tag for blur tool */ if (vpd->mlooptag) @@ -2980,7 +2980,7 @@ static int weight_from_bones_exec(bContext *C, wmOperator *op) Mesh *me = ob->data; int type = RNA_enum_get(op->ptr, "type"); - create_vgroups_from_armature(op->reports, scene, ob, armob, type, (me->editflag & ME_EDIT_MIRROR_X)); + create_vgroups_from_armature(op->reports, C, scene, ob, armob, type, (me->editflag & ME_EDIT_MIRROR_X)); DEG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); @@ -3190,6 +3190,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) struct ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + EvaluationContext eval_ctx; Mesh *me = ob->data; int x_start = RNA_int_get(op->ptr, "xstart"); int y_start = RNA_int_get(op->ptr, "ystart"); @@ -3198,7 +3199,11 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) float sco_start[2] = {x_start, y_start}; float sco_end[2] = {x_end, y_end}; const bool is_interactive = (gesture != NULL); - DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); + DerivedMesh *dm; + + CTX_data_eval_ctx(C, &eval_ctx); + + dm = mesh_get_derived_final(&eval_ctx, scene, ob, scene->customdata_mask); DMGradient_userData data = {NULL}; diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c index c939eb6df35..c9915a294ad 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c @@ -42,6 +42,8 @@ #include "BKE_DerivedMesh.h" #include "BKE_context.h" +#include "DEG_depsgraph.h" + #include "ED_screen.h" #include "ED_view3d.h" @@ -98,13 +100,16 @@ static void vpaint_proj_dm_map_cosnos_init__map_cb(void *userData, int index, co } } -static void vpaint_proj_dm_map_cosnos_init(Scene *scene, Object *ob, +static void vpaint_proj_dm_map_cosnos_init(const bContext *C, Scene *scene, Object *ob, struct VertProjHandle *vp_handle) { + EvaluationContext eval_ctx; Mesh *me = ob->data; DerivedMesh *dm; - dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); + CTX_data_eval_ctx(C, &eval_ctx); + + dm = mesh_get_derived_final(&eval_ctx, scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); if (dm->foreachMappedVert) { memset(vp_handle->vcosnos, 0, sizeof(DMCoNo) * me->totvert); @@ -169,11 +174,14 @@ static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index, } } -static void vpaint_proj_dm_map_cosnos_update(struct VertProjHandle *vp_handle, +static void vpaint_proj_dm_map_cosnos_update(const bContext *C, struct VertProjHandle *vp_handle, ARegion *ar, const float mval_fl[2]) { + EvaluationContext eval_ctx; struct VertProjUpdate vp_update = {vp_handle, ar, mval_fl}; + CTX_data_eval_ctx(C, &eval_ctx); + Scene *scene = vp_handle->scene; Object *ob = vp_handle->ob; Mesh *me = ob->data; @@ -182,7 +190,7 @@ static void vpaint_proj_dm_map_cosnos_update(struct VertProjHandle *vp_handle, /* quick sanity check - we shouldn't have to run this if there are no modifiers */ BLI_assert(BLI_listbase_is_empty(&ob->modifiers) == false); - dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); + dm = mesh_get_derived_final(&eval_ctx, scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); /* highly unlikely this will become unavailable once painting starts (perhaps with animated modifiers) */ if (LIKELY(dm->foreachMappedVert)) { @@ -198,7 +206,7 @@ static void vpaint_proj_dm_map_cosnos_update(struct VertProjHandle *vp_handle, /* -------------------------------------------------------------------- */ /* Public Functions */ -struct VertProjHandle *ED_vpaint_proj_handle_create(Scene *scene, Object *ob, +struct VertProjHandle *ED_vpaint_proj_handle_create(const bContext *C, Scene *scene, Object *ob, DMCoNo **r_vcosnos) { struct VertProjHandle *vp_handle = MEM_mallocN(sizeof(struct VertProjHandle), __func__); @@ -209,7 +217,7 @@ struct VertProjHandle *ED_vpaint_proj_handle_create(Scene *scene, Object *ob, vp_handle->use_update = false; /* sets 'use_update' if needed */ - vpaint_proj_dm_map_cosnos_init(scene, ob, vp_handle); + vpaint_proj_dm_map_cosnos_init(C, scene, ob, vp_handle); if (vp_handle->use_update) { vp_handle->dists_sq = MEM_mallocN(sizeof(float) * me->totvert, __func__); @@ -228,11 +236,11 @@ struct VertProjHandle *ED_vpaint_proj_handle_create(Scene *scene, Object *ob, return vp_handle; } -void ED_vpaint_proj_handle_update(struct VertProjHandle *vp_handle, +void ED_vpaint_proj_handle_update(const bContext *C, struct VertProjHandle *vp_handle, ARegion *ar, const float mval_fl[2]) { if (vp_handle->use_update) { - vpaint_proj_dm_map_cosnos_update(vp_handle, ar, mval_fl); + vpaint_proj_dm_map_cosnos_update(C, vp_handle, ar, mval_fl); } } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 9be196d1561..ac1c16f1d76 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -4394,10 +4394,13 @@ static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob) SculptSession *ss = ob->sculpt; if (ss->kb || ss->modifiers_active) { + EvaluationContext eval_ctx; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); - BKE_sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob, + CTX_data_eval_ctx(C, &eval_ctx); + + BKE_sculpt_update_mesh_elements(&eval_ctx, CTX_data_scene(C), sd, ob, sculpt_any_smooth_mode(brush, ss->cache, 0), false); } } @@ -4554,12 +4557,15 @@ static bool sculpt_brush_stroke_init(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); Sculpt *sd = CTX_data_tool_settings(C)->sculpt; + EvaluationContext eval_ctx; SculptSession *ss = CTX_data_active_object(C)->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); int mode = RNA_enum_get(op->ptr, "mode"); bool is_smooth; bool need_mask = false; + CTX_data_eval_ctx(C, &eval_ctx); + if (brush->sculpt_tool == SCULPT_TOOL_MASK) { need_mask = true; } @@ -4568,7 +4574,7 @@ static bool sculpt_brush_stroke_init(bContext *C, wmOperator *op) sculpt_brush_init_tex(scene, sd, ss); is_smooth = sculpt_any_smooth_mode(brush, NULL, mode); - BKE_sculpt_update_mesh_elements(scene, sd, ob, is_smooth, need_mask); + BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, is_smooth, need_mask); return 1; } @@ -4663,8 +4669,11 @@ static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const float mouse[2]) { /* Don't start the stroke until mouse goes over the mesh. - * note: mouse will only be null when re-executing the saved stroke. */ - if (!mouse || over_mesh(C, op, mouse[0], mouse[1])) { + * note: mouse will only be null when re-executing the saved stroke. + * We have exception for 'exec' strokes since they may not set 'mouse', only 'location', see: T52195. */ + if (((op->flag & OP_IS_INVOKE) == 0) || + (mouse == NULL) || over_mesh(C, op, mouse[0], mouse[1])) + { Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; @@ -4995,10 +5004,13 @@ void sculpt_update_after_dynamic_topology_toggle(bContext *C) { Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + EvaluationContext eval_ctx; Sculpt *sd = scene->toolsettings->sculpt; + CTX_data_eval_ctx(C, &eval_ctx); + /* Create the PBVH */ - BKE_sculpt_update_mesh_elements(scene, sd, ob, false, false); + BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, false, false); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); } @@ -5332,11 +5344,15 @@ static void SCULPT_OT_symmetrize(wmOperatorType *ot) /**** Toggle operator for turning sculpt mode on or off ****/ -static void sculpt_init_session(Scene *scene, Object *ob) +static void sculpt_init_session(const bContext *C, Scene *scene, Object *ob) { + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); + ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session"); - BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0, false); + BKE_sculpt_update_mesh_elements(&eval_ctx, scene, scene->toolsettings->sculpt, ob, 0, false); } @@ -5428,7 +5444,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) if (ob->sculpt) BKE_sculptsession_free(ob); - sculpt_init_session(scene, ob); + sculpt_init_session(C, scene, ob); /* Mask layer is required */ if (mmd) { diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 9d55cc1369e..a10c7477dc6 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -127,9 +127,12 @@ static bool sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoN Scene *scene = CTX_data_scene(C); Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Object *ob = CTX_data_active_object(C); + EvaluationContext eval_ctx; SculptSession *ss = ob->sculpt; MVert *mvert; int *index; + + CTX_data_eval_ctx(C, &eval_ctx); if (unode->maxvert) { /* regular mesh restore */ @@ -143,7 +146,7 @@ static bool sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoN if (kb) { ob->shapenr = BLI_findindex(&key->block, kb) + 1; - BKE_sculpt_update_mesh_elements(scene, sd, ob, 0, false); + BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, 0, false); WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob); } else { @@ -451,6 +454,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb) Scene *scene = CTX_data_scene(C); Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Object *ob = CTX_data_active_object(C); + EvaluationContext eval_ctx; DerivedMesh *dm; SculptSession *ss = ob->sculpt; SculptUndoNode *unode; @@ -458,6 +462,8 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb) bool need_mask = false; bool partial_update = true; + CTX_data_eval_ctx(C, &eval_ctx); + for (unode = lb->first; unode; unode = unode->next) { if (STREQ(unode->idname, ob->id.name)) { if (unode->type == SCULPT_UNDO_MASK) { @@ -469,10 +475,10 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb) } } - BKE_sculpt_update_mesh_elements(scene, sd, ob, 0, need_mask); + BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, 0, need_mask); /* call _after_ sculpt_update_mesh_elements() which may update 'ob->derivedFinal' */ - dm = mesh_get_derived_final(scene, ob, 0); + dm = mesh_get_derived_final(&eval_ctx, scene, ob, 0); if (lb->first && sculpt_undo_bmesh_restore(C, lb->first, ob, ss)) return; diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 95ff76e48cc..f5680bf2265 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -384,9 +384,11 @@ static void draw_stabilization_border(SpaceClip *sc, ARegion *ar, int width, int static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track) { +#define MAX_STATIC_PATH 64 int count = sc->path_length; int i, a, b, curindex = -1; - float path[102][2]; + float path_static[(MAX_STATIC_PATH + 1) * 2][2]; + float (*path)[2]; int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr, start_frame; MovieTrackingMarker *marker; @@ -399,6 +401,13 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin if (marker->framenr != framenr || marker->flag & MARKER_DISABLED) return; + if (count < MAX_STATIC_PATH) { + path = path_static; + } + else { + path = MEM_mallocN(sizeof(*path) * (count + 1) * 2, "path"); + } + a = count; i = framenr - 1; while (i >= framenr - count) { @@ -533,6 +542,11 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin } immUnbindProgram(); + + if (path != path_static) { + MEM_freeN(path); + } +#undef MAX_STATIC_PATH } static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index eed2acbfc68..9af3ebf3cbb 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -821,7 +821,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) #endif } -const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL}; +static const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL}; static int clip_context(const bContext *C, const char *member, bContextDataResult *result) { diff --git a/source/blender/editors/space_clip/tracking_ops_orient.c b/source/blender/editors/space_clip/tracking_ops_orient.c index 671825ef7c3..7b21e11d342 100644 --- a/source/blender/editors/space_clip/tracking_ops_orient.c +++ b/source/blender/editors/space_clip/tracking_ops_orient.c @@ -406,6 +406,7 @@ static int set_plane_exec(bContext *C, wmOperator *op) ListBase *tracksbase; Object *object; Object *camera = get_camera_with_movieclip(scene, clip); + EvaluationContext eval_ctx; int tot = 0; float vec[3][3], mat[4][4], obmat[4][4], newmat[4][4], orig[3] = {0.0f, 0.0f, 0.0f}; int plane = RNA_enum_get(op->ptr, "plane"); @@ -430,6 +431,8 @@ static int set_plane_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + CTX_data_eval_ctx(C, &eval_ctx); + BKE_tracking_get_camera_object_matrix(scene, camera, mat); /* Get 3 bundles to use as reference. */ @@ -492,7 +495,7 @@ static int set_plane_exec(bContext *C, wmOperator *op) BKE_object_apply_mat4(object, mat, 0, 0); } - BKE_object_where_is_calc(scene, object); + BKE_object_where_is_calc(&eval_ctx, scene, object); set_axis(scene, object, clip, tracking_object, axis_track, 'X'); DEG_id_tag_update(&clip->id, 0); diff --git a/source/blender/editors/space_clip/tracking_ops_track.c b/source/blender/editors/space_clip/tracking_ops_track.c index 368cbeaf955..42b017e6324 100644 --- a/source/blender/editors/space_clip/tracking_ops_track.c +++ b/source/blender/editors/space_clip/tracking_ops_track.c @@ -212,7 +212,7 @@ static int track_markers_initjob(bContext *C, } } - tmj->context = BKE_autotrack_context_new(clip, &sc->user, backwards, 1); + tmj->context = BKE_autotrack_context_new(clip, &sc->user, backwards, true); clip->tracking_context = tmj->context; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 6c33091ff01..d94aad640b7 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -277,9 +277,10 @@ typedef struct FileListFilter { /* FileListFilter.flags */ enum { - FLF_HIDE_DOT = 1 << 0, - FLF_HIDE_PARENT = 1 << 1, - FLF_HIDE_LIB_DIR = 1 << 2, + FLF_DO_FILTER = 1 << 0, + FLF_HIDE_DOT = 1 << 1, + FLF_HIDE_PARENT = 1 << 2, + FLF_HIDE_LIB_DIR = 1 << 3, }; typedef struct FileList { @@ -594,24 +595,27 @@ static bool is_filtered_file(FileListInternEntry *file, const char *UNUSED(root) { bool is_filtered = !is_hidden_file(file->relpath, filter); - if (is_filtered && filter->filter && !FILENAME_IS_CURRPAR(file->relpath)) { - if (file->typeflag & FILE_TYPE_DIR) { - if (file->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) { - if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) { - is_filtered = false; + if (is_filtered && (filter->flags & FLF_DO_FILTER) && !FILENAME_IS_CURRPAR(file->relpath)) { + /* We only check for types if some type are enabled in filtering. */ + if (filter->filter) { + if (file->typeflag & FILE_TYPE_DIR) { + if (file->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) { + if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) { + is_filtered = false; + } + } + else { + if (!(filter->filter & FILE_TYPE_FOLDER)) { + is_filtered = false; + } } } else { - if (!(filter->filter & FILE_TYPE_FOLDER)) { + if (!(file->typeflag & filter->filter)) { is_filtered = false; } } } - else { - if (!(file->typeflag & filter->filter)) { - is_filtered = false; - } - } if (is_filtered && (filter->filter_search[0] != '\0')) { if (fnmatch(filter->filter_search, file->relpath, FNM_CASEFOLD) != 0) { is_filtered = false; @@ -631,28 +635,31 @@ static bool is_filtered_lib(FileListInternEntry *file, const char *root, FileLis if (BLO_library_path_explode(path, dir, &group, &name)) { is_filtered = !is_hidden_file(file->relpath, filter); - if (is_filtered && filter->filter && !FILENAME_IS_CURRPAR(file->relpath)) { - if (file->typeflag & FILE_TYPE_DIR) { - if (file->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) { - if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) { - is_filtered = false; + if (is_filtered && (filter->flags & FLF_DO_FILTER) && !FILENAME_IS_CURRPAR(file->relpath)) { + /* We only check for types if some type are enabled in filtering. */ + if (filter->filter || filter->filter_id) { + if (file->typeflag & FILE_TYPE_DIR) { + if (file->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) { + if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) { + is_filtered = false; + } } - } - else { - if (!(filter->filter & FILE_TYPE_FOLDER)) { - is_filtered = false; + else { + if (!(filter->filter & FILE_TYPE_FOLDER)) { + is_filtered = false; + } } } - } - if (is_filtered && group) { - if (!name && (filter->flags & FLF_HIDE_LIB_DIR)) { - is_filtered = false; - } - else { - unsigned int filter_id = groupname_to_filter_id(group); - if (!(filter_id & filter->filter_id)) { + if (is_filtered && group) { + if (!name && (filter->flags & FLF_HIDE_LIB_DIR)) { is_filtered = false; } + else { + unsigned int filter_id = groupname_to_filter_id(group); + if (!(filter_id & filter->filter_id)) { + is_filtered = false; + } + } } } if (is_filtered && (filter->filter_search[0] != '\0')) { @@ -729,12 +736,17 @@ void filelist_filter(FileList *filelist) MEM_freeN(filtered_tmp); } -void filelist_setfilter_options(FileList *filelist, const bool hide_dot, const bool hide_parent, +void filelist_setfilter_options(FileList *filelist, const bool do_filter, + const bool hide_dot, const bool hide_parent, const unsigned int filter, const unsigned int filter_id, const char *filter_glob, const char *filter_search) { bool update = false; + if (((filelist->filter_data.flags & FLF_DO_FILTER) != 0) != (do_filter != 0)) { + filelist->filter_data.flags ^= FLF_DO_FILTER; + update = true; + } if (((filelist->filter_data.flags & FLF_HIDE_DOT) != 0) != (hide_dot != 0)) { filelist->filter_data.flags ^= FLF_HIDE_DOT; update = true; @@ -1104,7 +1116,10 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat preview->img = IMB_thumb_manage(preview->path, THB_LARGE, source); IMB_thumb_path_unlock(preview->path); - preview->flags = 0; /* Used to tell free func to not free anything! */ + /* Used to tell free func to not free anything. + * Note that we do not care about cas result here, + * we only want value attribution itself to be atomic (and memory barier).*/ + atomic_cas_uint32(&preview->flags, preview->flags, 0); BLI_thread_queue_push(cache->previews_done, preview); // printf("%s: End (%d)...\n", __func__, threadid); diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index f4304681780..4e9c1e0dd1d 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -68,7 +68,8 @@ int folderlist_clear_next(struct SpaceFile *sfile); void filelist_setsorting(struct FileList *filelist, const short sort); void filelist_sort(struct FileList *filelist); -void filelist_setfilter_options(struct FileList *filelist, const bool hide_dot, const bool hide_parent, +void filelist_setfilter_options(struct FileList *filelist, const bool do_filter, + const bool hide_dot, const bool hide_parent, const unsigned int filter, const unsigned int filter_id, const char *filter_glob, const char *filter_search); void filelist_filter(struct FileList *filelist); diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 269b1146ba0..6e4815af032 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -223,9 +223,10 @@ static void file_refresh(const bContext *C, ScrArea *sa) filelist_setdir(sfile->files, params->dir); filelist_setrecursion(sfile->files, params->recursion_level); filelist_setsorting(sfile->files, params->sort); - filelist_setfilter_options(sfile->files, (params->flag & FILE_HIDE_DOT) != 0, + filelist_setfilter_options(sfile->files, (params->flag & FILE_FILTER) != 0, + (params->flag & FILE_HIDE_DOT) != 0, false, /* TODO hide_parent, should be controllable? */ - (params->flag & FILE_FILTER) ? params->filter : 0, + params->filter, params->filter_id, params->filter_glob, params->filter_search); diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 1739569767e..01dc272ead4 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -259,7 +259,7 @@ static void draw_fcurve_handle_vertices(FCurve *fcu, View2D *v2d, bool sel_handl immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA); /* set handle size */ - immUniform1f("size", (UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) + 1.0f) * U.pixelsize); + immUniform1f("size", (1.4f * UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE)) * U.pixelsize); immUniform1f("outlineWidth", 1.0f * U.pixelsize); draw_fcurve_selected_handle_vertices(fcu, v2d, false, sel_handle_only, pos); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 659dfbfd57d..1cd2fcb442b 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1172,6 +1172,7 @@ static int image_sequence_get_len(ListBase *frames, int *ofs) } return frame_curr - (*ofs); } + *ofs = 0; return 0; } diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c index 914f8ffbe10..9d750bfe348 100644 --- a/source/blender/editors/space_node/node_group.c +++ b/source/blender/editors/space_node/node_group.c @@ -37,6 +37,7 @@ #include "DNA_anim_types.h" #include "BLI_listbase.h" +#include "BLI_linklist.h" #include "BLI_math.h" #include "BLT_translation.h" @@ -186,6 +187,7 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode) bNode *node, *nextnode; bNodeTree *ngroup, *wgroup; ListBase anim_basepaths = {NULL, NULL}; + LinkNode *nodes_delayed_free = NULL; ngroup = (bNodeTree *)gnode->id; @@ -208,8 +210,8 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode) * This also removes remaining links to and from interface nodes. */ if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) { - nodeFreeNode(wgroup, node); - continue; + /* We must delay removal since sockets will reference this node. see: T52092 */ + BLI_linklist_prepend(&nodes_delayed_free, node); } /* keep track of this node's RNA "base" path (the part of the path identifying the node) @@ -336,6 +338,11 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode) } } + while (nodes_delayed_free) { + node = BLI_linklist_pop(&nodes_delayed_free); + nodeFreeNode(ntree, node); + } + /* delete the group instance */ nodeFreeNode(ntree, gnode); diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index b425a92f601..7e8d092cdbe 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -221,6 +221,7 @@ void NODE_OT_clear_viewer_border(struct wmOperatorType *ot); /* node_widgets.c */ void NODE_WGT_backdrop_transform(struct wmManipulatorGroupType *wgt); +void NODE_WGT_backdrop_crop(struct wmManipulatorGroupType *wgt); extern const char *node_context_dir[]; diff --git a/source/blender/editors/space_node/node_manipulators.c b/source/blender/editors/space_node/node_manipulators.c index 8b4ebd70874..8f614137a84 100644 --- a/source/blender/editors/space_node/node_manipulators.c +++ b/source/blender/editors/space_node/node_manipulators.c @@ -22,9 +22,14 @@ * \ingroup spnode */ +#include <math.h> + #include "BKE_context.h" #include "BKE_image.h" +#include "BLI_math_matrix.h" +#include "BLI_math_vector.h" + #include "ED_screen.h" #include "ED_manipulator_library.h" @@ -40,6 +45,11 @@ #include "node_intern.h" +/* -------------------------------------------------------------------- */ + +/** \name Backdrop Manipulator + * \{ */ + static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) { SpaceNode *snode = CTX_wm_space_node(C); @@ -51,7 +61,7 @@ static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmManipulatorGrou if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) { bNode *node = nodeGetActive(snode->edittree); - if (node && node->type == CMP_NODE_VIEWER) { + if (node && ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { return true; } } @@ -63,7 +73,7 @@ static void WIDGETGROUP_node_transform_setup(const bContext *UNUSED(C), wmManipu { wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__); - wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, "backdrop_cage", NULL); + wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL); RNA_enum_set(wwrapper->manipulator->ptr, "transform", ED_MANIPULATOR_RECT_TRANSFORM_FLAG_TRANSLATE | ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM); @@ -108,7 +118,7 @@ static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmManipulatorG void NODE_WGT_backdrop_transform(wmManipulatorGroupType *wgt) { - wgt->name = "Backdrop Transform Widgets"; + wgt->name = "Backdrop Transform Widget"; wgt->idname = "NODE_WGT_backdrop_transform"; wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT; @@ -117,3 +127,249 @@ void NODE_WGT_backdrop_transform(wmManipulatorGroupType *wgt) wgt->setup = WIDGETGROUP_node_transform_setup; wgt->refresh = WIDGETGROUP_node_transform_refresh; } + +/** \} */ + +/* -------------------------------------------------------------------- */ + +/** \name Crop Manipulator + * \{ */ + +struct NodeCropWidgetGroup { + wmManipulator *border; + + struct { + float dims[2]; + } state; + + struct { + PointerRNA ptr; + PropertyRNA *prop; + bContext *context; + } update_data; +}; + +static void manipulator_node_crop_update(struct NodeCropWidgetGroup *crop_group) +{ + RNA_property_update(crop_group->update_data.context, &crop_group->update_data.ptr, crop_group->update_data.prop); +} + +static void two_xy_to_rect(const NodeTwoXYs *nxy, rctf *rect, const float dims[2], bool is_relative) +{ + if (is_relative) { + rect->xmin = nxy->fac_x1; + rect->xmax = nxy->fac_x2; + rect->ymin = nxy->fac_y1; + rect->ymax = nxy->fac_y2; + } + else { + rect->xmin = nxy->x1 / dims[0]; + rect->xmax = nxy->x2 / dims[0]; + rect->ymin = nxy->y1 / dims[1]; + rect->ymax = nxy->y2 / dims[1]; + } +} + +static void two_xy_from_rect(NodeTwoXYs *nxy, const rctf *rect, const float dims[2], bool is_relative) +{ + if (is_relative) { + nxy->fac_x1 = rect->xmin; + nxy->fac_x2 = rect->xmax; + nxy->fac_y1 = rect->ymin; + nxy->fac_y2 = rect->ymax; + } + else { + nxy->x1 = rect->xmin * dims[0]; + nxy->x2 = rect->xmax * dims[0]; + nxy->y1 = rect->ymin * dims[1]; + nxy->y2 = rect->ymax * dims[1]; + } +} + +/* scale callbacks */ +static void manipulator_node_crop_prop_size_get( + const wmManipulator *mpr, wmManipulatorProperty *mpr_prop, + void *value_p) +{ + float *value = value_p; + struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata; + const float *dims = crop_group->state.dims; + BLI_assert(mpr_prop->type->array_length == 2); + const bNode *node = mpr_prop->custom_func.user_data; + const NodeTwoXYs *nxy = node->storage; + bool is_relative = (bool)node->custom2; + rctf rct; + two_xy_to_rect(nxy, &rct, dims, is_relative); + value[0] = BLI_rctf_size_x(&rct); + value[1] = BLI_rctf_size_y(&rct); +} + +static void manipulator_node_crop_prop_size_set( + const wmManipulator *mpr, wmManipulatorProperty *mpr_prop, + const void *value_p) +{ + const float *value = value_p; + struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata; + const float *dims = crop_group->state.dims; + bNode *node = mpr_prop->custom_func.user_data; + NodeTwoXYs *nxy = node->storage; + bool is_relative = (bool)node->custom2; + BLI_assert(mpr_prop->type->array_length == 2); + rctf rct; + two_xy_to_rect(nxy, &rct, dims, is_relative); + BLI_rctf_resize(&rct, value[0], value[1]); + BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, &rct, &rct); + two_xy_from_rect(nxy, &rct, dims, is_relative); + + manipulator_node_crop_update(crop_group); +} + +/* offset callbacks */ +static void manipulator_node_crop_prop_offset_get( + const wmManipulator *mpr, wmManipulatorProperty *mpr_prop, + void *value_p) +{ + float *value = value_p; + struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata; + const float *dims = crop_group->state.dims; + BLI_assert(mpr_prop->type->array_length == 2); + const bNode *node = mpr_prop->custom_func.user_data; + const NodeTwoXYs *nxy = node->storage; + bool is_relative = (bool)node->custom2; + rctf rct; + two_xy_to_rect(nxy, &rct, dims, is_relative); + value[0] = (BLI_rctf_cent_x(&rct) - 0.5f) * dims[0]; + value[1] = (BLI_rctf_cent_y(&rct) - 0.5f) * dims[1]; +} + +static void manipulator_node_crop_prop_offset_set( + const wmManipulator *mpr, wmManipulatorProperty *mpr_prop, + const void *value_p) +{ + const float *value = value_p; + struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata; + const float *dims = crop_group->state.dims; + bNode *node = mpr_prop->custom_func.user_data; + NodeTwoXYs *nxy = node->storage; + bool is_relative = (bool)node->custom2; + BLI_assert(mpr_prop->type->array_length == 2); + rctf rct; + two_xy_to_rect(nxy, &rct, dims, is_relative); + BLI_rctf_recenter(&rct, (value[0] / dims[0]) + 0.5f, (value[1] / dims[1]) + 0.5f); + BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, &rct, &rct); + two_xy_from_rect(nxy, &rct, dims, is_relative); + + manipulator_node_crop_update(crop_group); +} + + +static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + + if ((snode->flag & SNODE_BACKDRAW) == 0) { + return false; + } + + if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) { + bNode *node = nodeGetActive(snode->edittree); + + if (node && ELEM(node->type, CMP_NODE_CROP)) { + /* ignore 'use_crop_size', we can't usefully edit the crop in this case. */ + if ((node->custom1 & (0 << 1)) == 0) { + return true; + } + } + } + + return false; +} + +static void WIDGETGROUP_node_crop_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) +{ + struct NodeCropWidgetGroup *crop_group = MEM_mallocN(sizeof(struct NodeCropWidgetGroup), __func__); + + crop_group->border = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL); + + RNA_enum_set(crop_group->border->ptr, "transform", + ED_MANIPULATOR_RECT_TRANSFORM_FLAG_TRANSLATE | ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE); + + mgroup->customdata = crop_group; +} + +static void WIDGETGROUP_node_crop_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup) +{ + ARegion *ar = CTX_wm_region(C); + wmManipulator *mpr = mgroup->manipulators.first; + + SpaceNode *snode = CTX_wm_space_node(C); + + unit_m4(mpr->matrix_space); + mul_v3_fl(mpr->matrix_space[0], snode->zoom); + mul_v3_fl(mpr->matrix_space[1], snode->zoom); + mpr->matrix_space[3][0] = (ar->winx / 2) + snode->xof; + mpr->matrix_space[3][1] = (ar->winy / 2) + snode->yof; +} + +static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmManipulatorGroup *mgroup) +{ + struct NodeCropWidgetGroup *crop_group = mgroup->customdata; + wmManipulator *mpr = crop_group->border; + + void *lock; + Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + + if (ibuf) { + crop_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f; + crop_group->state.dims[1] = (ibuf->y > 0) ? ibuf->y : 64.0f; + + RNA_float_set_array(mpr->ptr, "dimensions", crop_group->state.dims); + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, false); + + SpaceNode *snode = CTX_wm_space_node(C); + bNode *node = nodeGetActive(snode->edittree); + + crop_group->update_data.context = (bContext *)C; + RNA_pointer_create((ID *)snode->edittree, &RNA_CompositorNodeCrop, node, &crop_group->update_data.ptr); + crop_group->update_data.prop = RNA_struct_find_property(&crop_group->update_data.ptr, "relative"); + + WM_manipulator_target_property_def_func( + mpr, "offset", + &(const struct wmManipulatorPropertyFnParams) { + .value_get_fn = manipulator_node_crop_prop_offset_get, + .value_set_fn = manipulator_node_crop_prop_offset_set, + .range_get_fn = NULL, + .user_data = node, + }); + + WM_manipulator_target_property_def_func( + mpr, "scale", + &(const struct wmManipulatorPropertyFnParams) { + .value_get_fn = manipulator_node_crop_prop_size_get, + .value_set_fn = manipulator_node_crop_prop_size_set, + .range_get_fn = NULL, + .user_data = node, + }); + } + else { + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, true); + } + + BKE_image_release_ibuf(ima, ibuf, lock); +} + +void NODE_WGT_backdrop_crop(wmManipulatorGroupType *wgt) +{ + wgt->name = "Backdrop Crop Widget"; + wgt->idname = "NODE_WGT_backdrop_crop"; + + wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT; + + wgt->poll = WIDGETGROUP_node_crop_poll; + wgt->setup = WIDGETGROUP_node_crop_setup; + wgt->draw_prepare = WIDGETGROUP_node_crop_draw_prepare; + wgt->refresh = WIDGETGROUP_node_crop_refresh; +} + +/** \} */ diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index c1099f38d92..bc4918430ef 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -866,6 +866,7 @@ static void node_widgets(void) wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure( &(const struct wmManipulatorMapType_Params){SPACE_NODE, RGN_TYPE_WINDOW}); WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_transform); + WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_crop); } static void node_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 17d7c8967de..498e1cfe87f 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1904,7 +1904,7 @@ static int parent_drop_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - ED_object_parent_set(op->reports, bmain, scene, ob, par, partype, false, false, NULL); + ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL); DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); @@ -1978,7 +1978,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) } if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { - if (ED_object_parent_set(op->reports, bmain, scene, ob, par, partype, false, false, NULL)) { + if (ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL)) { DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 568927425a9..adb019766ea 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -1944,7 +1944,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops outliner_add_orphaned_datablocks(mainvar, soops); } else if (soops->outlinevis == SO_ACT_LAYER) { - outliner_add_collections_act_layer(soops, BKE_scene_layer_context_active_PLACEHOLDER(scene)); + outliner_add_collections_act_layer(soops, sl); } else if (soops->outlinevis == SO_COLLECTIONS) { outliner_add_collections_master(soops, scene); diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index b3ec2948c8c..5dfcba9b4d1 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -436,7 +436,7 @@ static void sequencer_dropboxes(void) /* ************* end drop *********** */ -const char *sequencer_context_dir[] = {"edit_mask", NULL}; +static const char *sequencer_context_dir[] = {"edit_mask", NULL}; static int sequencer_context(const bContext *C, const char *member, bContextDataResult *result) { diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index c442b1a377d..6802658803b 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -60,7 +60,9 @@ set(SRC view3d_walk.c view3d_header.c view3d_iterators.c - view3d_manipulators.c + view3d_manipulator_camera.c + view3d_manipulator_forcefield.c + view3d_manipulator_lamp.c view3d_ops.c view3d_project.c view3d_ruler.c diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index 115574a5ffe..191dfed01bf 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -54,6 +54,9 @@ #include "BKE_modifier.h" #include "BKE_nla.h" #include "BKE_curve.h" +#include "BKE_context.h" + +#include "DEG_depsgraph.h" #include "BIF_glutil.h" @@ -1607,7 +1610,7 @@ static void draw_bone(const short dt, int armflag, int boneflag, short constflag } } -static void draw_custom_bone(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob, +static void draw_custom_bone(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob, const short dt, int armflag, int boneflag, unsigned int id, float length) { if (ob == NULL) return; @@ -1623,7 +1626,7 @@ static void draw_custom_bone(Scene *scene, SceneLayer *sl, View3D *v3d, RegionVi GPU_select_load_id((GLuint) id | BONESEL_BONE); } - draw_object_instance(scene, sl, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE, fcolor); + draw_object_instance(C, scene, sl, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE, fcolor); } @@ -1927,7 +1930,7 @@ static void bone_matrix_translate_y(float mat[4][4], float y) } /* assumes object is Armature with pose */ -static void draw_pose_bones(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base, +static void draw_pose_bones(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base, const short dt, const unsigned char ob_wire_col[4], const bool do_const_color, const bool is_outline) { @@ -2054,7 +2057,7 @@ static void draw_pose_bones(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion * glDisable(GL_CULL_FACE); } - draw_custom_bone(scene, sl, v3d, rv3d, pchan->custom, + draw_custom_bone(C, scene, sl, v3d, rv3d, pchan->custom, OB_SOLID, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan)); } } @@ -2150,7 +2153,7 @@ static void draw_pose_bones(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion * if (bone == arm->act_bone) flag |= BONE_DRAW_ACTIVE; - draw_custom_bone(scene, sl, v3d, rv3d, pchan->custom, + draw_custom_bone(C, scene, sl, v3d, rv3d, pchan->custom, OB_WIRE, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan)); gpuPopMatrix(); @@ -2656,8 +2659,9 @@ static void ghost_poses_tag_unselected(Object *ob, short unset) /* draw ghosts that occur within a frame range * note: object should be in posemode */ -static void draw_ghost_poses_range(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base) +static void draw_ghost_poses_range(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base) { + EvaluationContext eval_ctx; Object *ob = base->object; AnimData *adt = BKE_animdata_from_id(&ob->id); bArmature *arm = ob->data; @@ -2665,6 +2669,8 @@ static void draw_ghost_poses_range(Scene *scene, SceneLayer *sl, View3D *v3d, AR float start, end, stepsize, range, colfac; int cfrao, flago; unsigned char col[4]; + + CTX_data_eval_ctx(C, &eval_ctx); start = (float)arm->ghostsf; end = (float)arm->ghostef; @@ -2700,8 +2706,8 @@ static void draw_ghost_poses_range(Scene *scene, SceneLayer *sl, View3D *v3d, AR UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col); BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(scene, ob); - draw_pose_bones(scene, sl, v3d, ar, base, OB_WIRE, col, true, false); + BKE_pose_where_is(&eval_ctx, scene, ob); + draw_pose_bones(C, scene, sl, v3d, ar, base, OB_WIRE, col, true, false); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2723,8 +2729,9 @@ static void draw_ghost_poses_range(Scene *scene, SceneLayer *sl, View3D *v3d, AR /* draw ghosts on keyframes in action within range * - object should be in posemode */ -static void draw_ghost_poses_keys(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, BaseLegacy *base) +static void draw_ghost_poses_keys(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, BaseLegacy *base) { + EvaluationContext eval_ctx; Object *ob = base->object; AnimData *adt = BKE_animdata_from_id(&ob->id); bAction *act = (adt) ? adt->action : NULL; @@ -2735,6 +2742,8 @@ static void draw_ghost_poses_keys(Scene *scene, SceneLayer *sl, View3D *v3d, ARe float start, end, range, colfac, i; int cfrao, flago; unsigned char col[4]; + + CTX_data_eval_ctx(C, &eval_ctx); start = (float)arm->ghostsf; end = (float)arm->ghostef; @@ -2781,8 +2790,8 @@ static void draw_ghost_poses_keys(Scene *scene, SceneLayer *sl, View3D *v3d, ARe CFRA = (int)ak->cfra; BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(scene, ob); - draw_pose_bones(scene, sl, v3d, ar, base, OB_WIRE, col, true, false); + BKE_pose_where_is(&eval_ctx, scene, ob); + draw_pose_bones(C, scene, sl, v3d, ar, base, OB_WIRE, col, true, false); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2805,8 +2814,9 @@ static void draw_ghost_poses_keys(Scene *scene, SceneLayer *sl, View3D *v3d, ARe /* draw ghosts around current frame * - object is supposed to be armature in posemode */ -static void draw_ghost_poses(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base) +static void draw_ghost_poses(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base) { + EvaluationContext eval_ctx; Object *ob = base->object; AnimData *adt = BKE_animdata_from_id(&ob->id); bArmature *arm = ob->data; @@ -2814,6 +2824,8 @@ static void draw_ghost_poses(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion float cur, start, end, stepsize, range, colfac, actframe, ctime; int cfrao, flago; unsigned char col[4]; + + CTX_data_eval_ctx(C, &eval_ctx); /* pre conditions, get an action with sufficient frames */ if (ELEM(NULL, adt, adt->action)) @@ -2859,8 +2871,8 @@ static void draw_ghost_poses(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(scene, ob); - draw_pose_bones(scene, sl, v3d, ar, base, OB_WIRE, col, true, false); + BKE_pose_where_is(&eval_ctx, scene, ob); + draw_pose_bones(C, scene, sl, v3d, ar, base, OB_WIRE, col, true, false); } } @@ -2874,8 +2886,8 @@ static void draw_ghost_poses(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(scene, ob); - draw_pose_bones(scene, sl, v3d, ar, base, OB_WIRE, col, true, false); + BKE_pose_where_is(&eval_ctx, scene, ob); + draw_pose_bones(C, scene, sl, v3d, ar, base, OB_WIRE, col, true, false); } } } @@ -2900,7 +2912,7 @@ static void draw_ghost_poses(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion /* called from drawobject.c, return true if nothing was drawn * (ob_wire_col == NULL) when drawing ghost */ -bool draw_armature(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base, +bool draw_armature(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base, const short dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_outline) { @@ -2960,14 +2972,14 @@ bool draw_armature(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base } else if (ob->mode & OB_MODE_POSE) { if (arm->ghosttype == ARM_GHOST_RANGE) { - draw_ghost_poses_range(scene, sl, v3d, ar, base); + draw_ghost_poses_range(C, scene, sl, v3d, ar, base); } else if (arm->ghosttype == ARM_GHOST_KEYS) { - draw_ghost_poses_keys(scene, sl, v3d, ar, base); + draw_ghost_poses_keys(C, scene, sl, v3d, ar, base); } else if (arm->ghosttype == ARM_GHOST_CUR) { if (arm->ghostep) - draw_ghost_poses(scene, sl, v3d, ar, base); + draw_ghost_poses(C, scene, sl, v3d, ar, base); } if ((dflag & DRAW_SCENESET) == 0) { if (ob == OBACT_NEW) @@ -2980,7 +2992,7 @@ bool draw_armature(Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base } } } - draw_pose_bones(scene, sl, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline); + draw_pose_bones(C, scene, sl, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline); arm->flag &= ~ARM_POSEMODE; } else { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index cec13651292..df187574777 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -54,6 +54,7 @@ #include "BKE_camera.h" #include "BKE_colortools.h" #include "BKE_constraint.h" /* for the get_constraint_target function */ +#include "BKE_context.h" #include "BKE_curve.h" #include "BKE_DerivedMesh.h" #include "BKE_deform.h" @@ -82,6 +83,8 @@ #include "BKE_editmesh.h" +#include "DEG_depsgraph.h" + #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -2393,7 +2396,7 @@ static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, i } #ifdef SEQUENCER_DAG_WORKAROUND -static void ensure_curve_cache(Scene *scene, Object *object) +static void ensure_curve_cache(const bContext *C, Scene *scene, Object *object) { bool need_recalc = object->curve_cache == NULL; /* Render thread might have freed the curve cache if the @@ -2418,17 +2421,21 @@ static void ensure_curve_cache(Scene *scene, Object *object) object->curve_cache->bev.first != NULL; } if (need_recalc) { + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); + switch (object->type) { case OB_CURVE: case OB_SURF: case OB_FONT: - BKE_displist_make_curveTypes(scene, object, false); + BKE_displist_make_curveTypes(&eval_ctx, scene, object, false); break; case OB_MBALL: - BKE_displist_make_mball(G.main->eval_ctx, scene, object); + BKE_displist_make_mball(&eval_ctx, scene, object); break; case OB_LATTICE: - BKE_lattice_modifiers_calc(scene, object); + BKE_lattice_modifiers_calc(&eval_ctx, scene, object); break; } } @@ -4294,7 +4301,7 @@ static bool object_is_halo(Scene *scene, Object *ob) return (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene)); } -static void draw_mesh_fancy(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, +static void draw_mesh_fancy(EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt, const unsigned char ob_wire_col[4], const short dflag) { #ifdef WITH_GAMEENGINE @@ -4305,7 +4312,7 @@ static void draw_mesh_fancy(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v Mesh *me = ob->data; eWireDrawMode draw_wire = OBDRAW_WIRE_OFF; bool /* no_verts,*/ no_edges, no_faces; - DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); + DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask); const bool is_obact = (ob == OBACT_NEW); int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0; @@ -4558,15 +4565,18 @@ static void draw_mesh_fancy(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v } /* returns true if nothing was drawn, for detecting to draw an object center */ -static bool draw_mesh_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, BaseLegacy *base, +static bool draw_mesh_object(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, BaseLegacy *base, const char dt, const unsigned char ob_wire_col[4], const short dflag) { + EvaluationContext eval_ctx; Object *ob = base->object; Object *obedit = scene->obedit; Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; bool do_alpha_after = false, drawlinked = false, retval = false; + CTX_data_eval_ctx(C, &eval_ctx); + /* If we are drawing shadows and any of the materials don't cast a shadow, * then don't draw the object */ if (v3d->flag2 & V3D_RENDER_SHADOW) { @@ -4599,7 +4609,7 @@ static bool draw_mesh_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D * } else { cageDM = editbmesh_get_derived_cage_and_final( - scene, ob, em, scene->customdata_mask, + &eval_ctx, scene, ob, em, scene->customdata_mask, &finalDM); } @@ -4640,7 +4650,7 @@ static bool draw_mesh_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D * } } - draw_mesh_fancy(scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); + draw_mesh_fancy(&eval_ctx, scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); GPU_end_object_materials(); @@ -4702,13 +4712,13 @@ static void make_color_variations(const unsigned char base_ubyte[4], float low[4 high[3] = base[3]; } -static void draw_mesh_fancy_new(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, +static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt, const unsigned char ob_wire_col[4], const short dflag, const bool other_obedit) { if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { /* too complicated! use existing methods */ /* TODO: move this into a separate depth pre-pass */ - draw_mesh_fancy(scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); + draw_mesh_fancy(eval_ctx, scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); return; } @@ -4720,7 +4730,7 @@ static void draw_mesh_fancy_new(Scene *scene, SceneLayer *sl, ARegion *ar, View3 Mesh *me = ob->data; eWireDrawMode draw_wire = OBDRAW_WIRE_OFF; /* could be bool draw_wire_overlay */ bool no_edges, no_faces; - DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); + DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask); const bool is_obact = (ob == OBACT_NEW); int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0; @@ -5020,15 +5030,18 @@ static void draw_mesh_fancy_new(Scene *scene, SceneLayer *sl, ARegion *ar, View3 dm->release(dm); } -static bool UNUSED_FUNCTION(draw_mesh_object_new)(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, BaseLegacy *base, +static bool UNUSED_FUNCTION(draw_mesh_object_new)(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, BaseLegacy *base, const char dt, const unsigned char ob_wire_col[4], const short dflag) { + EvaluationContext eval_ctx; Object *ob = base->object; Object *obedit = scene->obedit; Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; bool do_alpha_after = false, drawlinked = false, retval = false; + CTX_data_eval_ctx(C, &eval_ctx); + if (v3d->flag2 & V3D_RENDER_SHADOW) { /* TODO: handle shadow pass separately */ return true; @@ -5058,7 +5071,7 @@ static bool UNUSED_FUNCTION(draw_mesh_object_new)(Scene *scene, SceneLayer *sl, } else { cageDM = editbmesh_get_derived_cage_and_final( - scene, ob, em, scene->customdata_mask, + &eval_ctx, scene, ob, em, scene->customdata_mask, &finalDM); } @@ -5106,7 +5119,7 @@ static bool UNUSED_FUNCTION(draw_mesh_object_new)(Scene *scene, SceneLayer *sl, const bool other_obedit = obedit && (obedit != ob); - draw_mesh_fancy_new(scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag, other_obedit); + draw_mesh_fancy_new(&eval_ctx, scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag, other_obedit); GPU_end_object_materials(); @@ -5573,7 +5586,7 @@ static bool drawDispList_nobackface(Scene *scene, SceneLayer *sl, View3D *v3d, R return false; } -static bool drawDispList(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base, +static bool drawDispList(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt, const short dflag, const unsigned char ob_wire_col[4]) { bool retval; @@ -5586,7 +5599,7 @@ static bool drawDispList(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D } #ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(scene, base->object); + ensure_curve_cache(C, scene, base->object); #endif if (drawCurveDerivedMesh(scene, sl, v3d, rv3d, base, dt) == false) { @@ -5895,7 +5908,7 @@ static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d, * 6. draw the arrays * 7. clean up */ -static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv3d, +static void draw_new_particle_system(EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, ParticleSystem *psys, const char ob_dt, const short dflag) { @@ -5946,6 +5959,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv curvemapping_changed_all(psys->part->roughcurve); /* 2. */ + sim.eval_ctx = eval_ctx; sim.scene = scene; sim.ob = ob; sim.psys = psys; @@ -6580,14 +6594,19 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv } } -static void draw_update_ptcache_edit(Scene *scene, SceneLayer *sl, Object *ob, PTCacheEdit *edit) +static void draw_update_ptcache_edit(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, PTCacheEdit *edit) { if (edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) - PE_update_object(scene, sl, ob, 0); + PE_update_object(C, scene, sl, ob, 0); /* create path and child path cache if it doesn't exist already */ - if (edit->pathcache == NULL) - psys_cache_edit_paths(scene, ob, edit, CFRA, G.is_rendering); + if (edit->pathcache == NULL) { + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); + + psys_cache_edit_paths(&eval_ctx, scene, ob, edit, CFRA, G.is_rendering); + } } static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit) @@ -7321,7 +7340,7 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel) } static void draw_editnurb( - Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb, + const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb, const char dt, const short dflag, const unsigned char UNUSED(ob_wire_col[4])) { ToolSettings *ts = scene->toolsettings; @@ -7335,7 +7354,7 @@ static void draw_editnurb( /* DispList */ UI_GetThemeColor3ubv(TH_WIRE_EDIT, wire_col); - drawDispList(scene, sl, v3d, rv3d, base, dt, dflag, wire_col); + drawDispList(C, scene, sl, v3d, rv3d, base, dt, dflag, wire_col); /* for shadows only show solid faces */ if (v3d->flag2 & V3D_RENDER_SHADOW) @@ -7460,7 +7479,7 @@ static void draw_editfont_textcurs(RegionView3D *rv3d, float textcurs[4][2]) immUnbindProgram(); } -static void draw_editfont(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base, +static void draw_editfont(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt, const short dflag, const unsigned char ob_wire_col[4]) { Object *ob = base->object; @@ -7473,11 +7492,11 @@ static void draw_editfont(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3 if (cu->flag & CU_FAST) { imm_cpack(0xFFFFFF); set_inverted_drawing(1); - drawDispList(scene, sl, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col); + drawDispList(C, scene, sl, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col); set_inverted_drawing(0); } else { - drawDispList(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); + drawDispList(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); } if (cu->linewidth != 0.0f) { @@ -7779,7 +7798,7 @@ static void imm_drawcone(const float vec[3], float radius, float height, float t } /* return true if nothing was drawn */ -static bool drawmball(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base, +static bool drawmball(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt, const short dflag, const unsigned char ob_wire_col[4]) { Object *ob = base->object; @@ -7793,13 +7812,13 @@ static bool drawmball(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *r if ((G.f & G_PICKSEL) == 0) { unsigned char wire_col[4]; UI_GetThemeColor4ubv(TH_WIRE_EDIT, wire_col); - drawDispList(scene, sl, v3d, rv3d, base, dt, dflag, wire_col); + drawDispList(C, scene, sl, v3d, rv3d, base, dt, dflag, wire_col); } ml = mb->editelems->first; } else { if ((base->flag_legacy & OB_FROMDUPLI) == 0) { - drawDispList(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); + drawDispList(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); } ml = mb->elems.first; } @@ -8247,7 +8266,7 @@ static void drawtexspace(Object *ob, const unsigned char ob_wire_col[3]) /* draws wire outline */ static void draw_object_selected_outline( - Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base, + const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base, const unsigned char ob_wire_col[4]) { RegionView3D *rv3d = ar->regiondata; @@ -8259,7 +8278,7 @@ static void draw_object_selected_outline( bool has_faces = false; #ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(scene, ob); + ensure_curve_cache(C, scene, ob); #endif DerivedMesh *dm = ob->derivedFinal; @@ -8296,7 +8315,7 @@ static void draw_object_selected_outline( else if (ob->type == OB_ARMATURE) { if (!(ob->mode & OB_MODE_POSE && base == sl->basact)) { glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); - draw_armature(scene, sl, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true); + draw_armature(C, scene, sl, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true); } } @@ -8548,7 +8567,7 @@ void draw_rigidbody_shape(Object *ob, const unsigned char ob_wire_col[4]) * main object drawing function, draws in selection * \param dflag (draw flag) can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET */ -void draw_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *base, const short dflag) +void draw_object(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *base, const short dflag) { ModifierData *md = NULL; Object *ob = base->object; @@ -8563,6 +8582,9 @@ void draw_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *b const bool has_particles = (ob->particlesystem.first != NULL); bool skip_object = false; /* Draw particles but not their emitter object. */ SmokeModifierData *smd = NULL; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); if (ob != scene->obedit) { if (ob->restrictflag & OB_RESTRICT_VIEW) @@ -8730,7 +8752,7 @@ void draw_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *b if ((v3d->flag & V3D_SELECT_OUTLINE) && !render_override && ob->type != OB_MESH) { if (dt > OB_WIRE && (ob->mode & (OB_MODE_EDIT | OB_MODE_HAIR_EDIT)) == 0 && (dflag & DRAW_SCENESET) == 0) { if (!(ob->dtx & OB_DRAWWIRE) && (base->flag & BASE_SELECTED) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) { - draw_object_selected_outline(scene, sl, v3d, ar, base, ob_wire_col); + draw_object_selected_outline(C, scene, sl, v3d, ar, base, ob_wire_col); } } } @@ -8744,7 +8766,7 @@ void draw_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *b switch (ob->type) { case OB_MESH: - empty_object = draw_mesh_object(scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); + empty_object = draw_mesh_object(C, scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); if ((dflag & DRAW_CONSTCOLOR) == 0) { /* mesh draws wire itself */ dtx &= ~OB_DRAWWIRE; @@ -8754,18 +8776,18 @@ void draw_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *b case OB_FONT: cu = ob->data; if (cu->editfont) { - draw_editfont(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); + draw_editfont(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); } else if (dt == OB_BOUNDBOX) { if ((render_override && v3d->drawtype >= OB_WIRE) == 0) { #ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(scene, base->object); + ensure_curve_cache(C, scene, base->object); #endif draw_bounding_volume(ob, ob->boundtype, ob_wire_col); } } else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) { - empty_object = drawDispList(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); + empty_object = drawDispList(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); } break; @@ -8775,18 +8797,18 @@ void draw_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *b if (cu->editnurb) { ListBase *nurbs = BKE_curve_editNurbs_get(cu); - draw_editnurb(scene, sl, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col); + draw_editnurb(C, scene, sl, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col); } else if (dt == OB_BOUNDBOX) { if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) { #ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(scene, base->object); + ensure_curve_cache(C, scene, base->object); #endif draw_bounding_volume(ob, ob->boundtype, ob_wire_col); } } else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) { - empty_object = drawDispList(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); + empty_object = drawDispList(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); } break; case OB_MBALL: @@ -8794,17 +8816,17 @@ void draw_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *b MetaBall *mb = ob->data; if (mb->editelems) - drawmball(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); + drawmball(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); else if (dt == OB_BOUNDBOX) { if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) { #ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(scene, base->object); + ensure_curve_cache(C, scene, base->object); #endif draw_bounding_volume(ob, ob->boundtype, ob_wire_col); } } else - empty_object = drawmball(scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); + empty_object = drawmball(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col); break; } case OB_EMPTY: @@ -8843,7 +8865,7 @@ void draw_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *b } else { #ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(scene, ob); + ensure_curve_cache(C, scene, ob); #endif drawlattice(v3d, ob, dflag, ob_wire_col); } @@ -8868,7 +8890,7 @@ void draw_object(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *b else copy_v4_v4_uchar(arm_col, ob_wire_col); - empty_object = draw_armature(scene, sl, v3d, ar, base, dt, dflag, arm_col, false); + empty_object = draw_armature(C, scene, sl, v3d, ar, base, dt, dflag, arm_col, false); } } break; @@ -8922,12 +8944,12 @@ afterdraw: if (!(ob->mode & OB_MODE_HAIR_EDIT)) { /* run this so that possible child particles get cached */ if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { - PTCacheEdit *edit = PE_create_current(scene, ob); + PTCacheEdit *edit = PE_create_current(C, scene, ob); if (edit && edit->psys == psys) - draw_update_ptcache_edit(scene, sl, ob, edit); + draw_update_ptcache_edit(C, scene, sl, ob, edit); } - draw_new_particle_system(scene, v3d, rv3d, base, psys, dt, dflag); + draw_new_particle_system(&eval_ctx, scene, v3d, rv3d, base, psys, dt, dflag); } } invert_m4_m4(ob->imat, ob->obmat); @@ -8944,10 +8966,10 @@ afterdraw: { if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { - PTCacheEdit *edit = PE_create_current(scene, ob); + PTCacheEdit *edit = PE_create_current(C, scene, ob); if (edit) { gpuLoadMatrix(rv3d->viewmat); - draw_update_ptcache_edit(scene, sl, ob, edit); + draw_update_ptcache_edit(C, scene, sl, ob, edit); draw_ptcache_edit(scene, v3d, edit); gpuMultMatrix(ob->obmat); } @@ -9269,7 +9291,7 @@ afterdraw: for (ct = targets.first; ct; ct = ct->next) { /* calculate target's matrix */ if (cti->get_target_matrix) - cti->get_target_matrix(curcon, cob, ct, BKE_scene_frame_get(scene)); + cti->get_target_matrix(&eval_ctx, curcon, cob, ct, BKE_scene_frame_get(scene)); else unit_m4(ct->matrix); @@ -9318,10 +9340,10 @@ afterdraw: * Drawing for selection picking, * caller must have called 'GPU_select_load_id(base->selcode)' first. */ -void draw_object_select(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *base, const short dflag) +void draw_object_select(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *base, const short dflag) { BLI_assert(dflag & DRAW_PICKING && dflag & DRAW_CONSTCOLOR); - draw_object(scene, sl, ar, v3d, base, dflag); + draw_object(C, scene, sl, ar, v3d, base, dflag); /* we draw duplicators for selection too */ if ((base->object->transflag & OB_DUPLI)) { @@ -9344,7 +9366,7 @@ void draw_object_select(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, char dt = tbase.object->dt; tbase.object->dt = MIN2(tbase.object->dt, base->object->dt); short dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx; - draw_object(scene, sl, ar, v3d, &tbase, dflag); + draw_object(C, scene, sl, ar, v3d, &tbase, dflag); tbase.object->dt = dt; tbase.object->dtx = dtx; @@ -9603,10 +9625,10 @@ static DMDrawOption bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index) } } -static void bbs_mesh_solid_verts(Scene *scene, Object *ob) +static void bbs_mesh_solid_verts(EvaluationContext *eval_ctx, Scene *scene, Object *ob) { Mesh *me = ob->data; - DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); + DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask); DM_update_materials(dm, ob); @@ -9638,10 +9660,13 @@ static void bbs_mesh_solid_faces(Scene *scene, Object *ob) GWN_batch_draw(batch); } -void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob) +void draw_object_backbufsel(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob) { + EvaluationContext eval_ctx; ToolSettings *ts = scene->toolsettings; + CTX_data_eval_ctx(C, &eval_ctx); + gpuMultMatrix(ob->obmat); glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); @@ -9653,7 +9678,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; - DerivedMesh *dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH); + DerivedMesh *dm = editbmesh_get_derived_cage(&eval_ctx, scene, ob, em, CD_MASK_BAREMESH); BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE); @@ -9690,7 +9715,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec /* currently vertex select only supports weight paint */ (ob->mode & OB_MODE_WEIGHT_PAINT)) { - bbs_mesh_solid_verts(scene, ob); + bbs_mesh_solid_verts(&eval_ctx, scene, ob); } else { bbs_mesh_solid_faces(scene, ob); @@ -9710,18 +9735,21 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec /* assumes all matrices/etc set OK */ /* helper function for drawing object instances - meshes */ -static void draw_object_mesh_instance(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, +static void draw_object_mesh_instance(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob, const short dt, int outline, const unsigned char ob_wire_col[4]) { + EvaluationContext eval_ctx; Mesh *me = ob->data; DerivedMesh *dm = NULL, *edm = NULL; + + CTX_data_eval_ctx(C, &eval_ctx); if (ob->mode & OB_MODE_EDIT) { edm = editbmesh_get_derived_base(ob, me->edit_btmesh, CD_MASK_BAREMESH); DM_update_materials(edm, ob); } else { - dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + dm = mesh_get_derived_final(&eval_ctx, scene, ob, CD_MASK_BAREMESH); DM_update_materials(dm, ob); } @@ -9757,7 +9785,7 @@ static void draw_object_mesh_instance(Scene *scene, SceneLayer *sl, View3D *v3d, if (dm) dm->release(dm); } -void draw_object_instance(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline, const float wire_col[4]) +void draw_object_instance(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline, const float wire_col[4]) { if (ob == NULL) return; @@ -9767,7 +9795,7 @@ void draw_object_instance(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3 switch (ob->type) { case OB_MESH: - draw_object_mesh_instance(scene, sl, v3d, rv3d, ob, dt, outline, bcol); + draw_object_mesh_instance(C, scene, sl, v3d, rv3d, ob, dt, outline, bcol); break; case OB_EMPTY: if (ob->empty_drawtype == OB_EMPTY_IMAGE) { @@ -9780,15 +9808,23 @@ void draw_object_instance(Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3 } } -void ED_draw_object_facemap(Scene *scene, Object *ob, const float col[4], const int facemap) +void ED_draw_object_facemap(const bContext *C, Scene *scene, Object *ob, const float col[4], const int facemap) { + EvaluationContext eval_ctx; DerivedMesh *dm = NULL; + CTX_data_eval_ctx(C, &eval_ctx); + /* happens on undo */ if (ob->type != OB_MESH || !ob->data) return; - dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + /* Temporary, happens on undo, would resolve but will eventually move away from DM. */ + if (ob->derivedFinal == NULL) { + return; + } + + dm = mesh_get_derived_final(&eval_ctx, scene, ob, CD_MASK_BAREMESH); if (!dm || !CustomData_has_layer(&dm->polyData, CD_FACEMAP)) return; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 10d4af0bb77..fa15fa5ca94 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -738,9 +738,12 @@ static void view3d_widgets(void) &(const struct wmManipulatorMapType_Params){SPACE_VIEW3D, RGN_TYPE_WINDOW}); WM_manipulatorgrouptype_append_and_link(mmap_type, TRANSFORM_WGT_manipulator); - WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp); + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_spot); + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_area); + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_target); WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_force_field); WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera); + WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera_view); } diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c index 8beb0ff84b0..9b07593e576 100644 --- a/source/blender/editors/space_view3d/view3d_camera_control.c +++ b/source/blender/editors/space_view3d/view3d_camera_control.c @@ -54,6 +54,7 @@ #include "BLI_utildefines.h" #include "BKE_object.h" +#include "BKE_context.h" #include "DEG_depsgraph.h" @@ -137,10 +138,13 @@ Object *ED_view3d_cameracontrol_object_get(View3DCameraControl *vctrl) * the view for first-person style navigation. */ struct View3DCameraControl *ED_view3d_cameracontrol_acquire( - Scene *scene, View3D *v3d, RegionView3D *rv3d, + const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d, const bool use_parent_root) { View3DCameraControl *vctrl; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); vctrl = MEM_callocN(sizeof(View3DCameraControl), __func__); @@ -177,7 +181,7 @@ struct View3DCameraControl *ED_view3d_cameracontrol_acquire( /* store the original camera loc and rot */ vctrl->obtfm = BKE_object_tfm_backup(ob_back); - BKE_object_where_is_calc(scene, v3d->camera); + BKE_object_where_is_calc(&eval_ctx, scene, v3d->camera); negate_v3_v3(rv3d->ofs, v3d->camera->obmat[3]); rv3d->dist = 0.0; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 835c4573801..04cc77ddd9c 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -119,7 +119,7 @@ static bool use_depth_doit(Scene *scene, View3D *v3d) /** * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore */ -void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect) +void ED_view3d_update_viewmat(EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect) { RegionView3D *rv3d = ar->regiondata; @@ -134,7 +134,7 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view if (viewmat) copy_m4_m4(rv3d->viewmat, viewmat); else - view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */ + view3d_viewmatrix_set(eval_ctx, scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */ /* update utility matrices */ mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat); @@ -181,11 +181,11 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view } static void view3d_main_region_setup_view( - Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect) + EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect) { RegionView3D *rv3d = ar->regiondata; - ED_view3d_update_viewmat(scene, v3d, ar, viewmat, winmat, rect); + ED_view3d_update_viewmat(eval_ctx, scene, v3d, ar, viewmat, winmat, rect); /* set for opengl */ gpuLoadProjectionMatrix(rv3d->winmat); @@ -235,11 +235,14 @@ static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, Reg * we do a small hack to replace it temporarily so we don't need to change the * view3d)main_region_setup_view() code to account for that. */ -static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect) +static void view3d_stereo3d_setup(const bContext *C, Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect) { bool is_left; const char *names[2] = { STEREO_LEFT_NAME, STEREO_RIGHT_NAME }; const char *viewname; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); /* show only left or right camera */ if (v3d->stereo3d_camera != STEREO_3D_ID) @@ -261,7 +264,7 @@ static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname); BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat); - view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL, rect); + view3d_main_region_setup_view(&eval_ctx, scene, v3d, ar, viewmat, NULL, rect); data->shiftx = shiftx; BLI_unlock_thread(LOCK_VIEW3D); @@ -275,7 +278,7 @@ static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const v3d->camera = camera; BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat); - view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL, rect); + view3d_main_region_setup_view(&eval_ctx, scene, v3d, ar, viewmat, NULL, rect); v3d->camera = view_ob; BLI_unlock_thread(LOCK_VIEW3D); @@ -286,17 +289,20 @@ static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const * Set the correct matrices */ void ED_view3d_draw_setup_view( - wmWindow *win, Scene *scene, ARegion *ar, View3D *v3d, + wmWindow *win, const bContext *C, Scene *scene, ARegion *ar, View3D *v3d, float viewmat[4][4], float winmat[4][4], const rcti *rect) { RegionView3D *rv3d = ar->regiondata; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); /* Setup the view matrix. */ if (view3d_stereo3d_active(win, scene, v3d, rv3d)) { - view3d_stereo3d_setup(scene, v3d, ar, rect); + view3d_stereo3d_setup(C, scene, v3d, ar, rect); } else { - view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, rect); + view3d_main_region_setup_view(&eval_ctx, scene, v3d, ar, viewmat, winmat, rect); } } @@ -696,7 +702,7 @@ static void drawrenderborder(ARegion *ar, View3D *v3d) } void ED_view3d_draw_depth( - struct Depsgraph *graph, + const bContext *C, struct Depsgraph *graph, ARegion *ar, View3D *v3d, bool alphaoverride) { Scene *scene = DEG_get_evaluated_scene(graph); @@ -712,7 +718,7 @@ void ED_view3d_draw_depth( U.glalphaclip = alphaoverride ? 0.5f : glalphaclip; /* not that nice but means we wont zoom into billboards */ U.obcenter_dia = 0; - ED_view3d_draw_setup_view(NULL, scene, ar, v3d, NULL, NULL, NULL); + ED_view3d_draw_setup_view(NULL, C, scene, ar, v3d, NULL, NULL, NULL); glClear(GL_DEPTH_BUFFER_BIT); @@ -1859,7 +1865,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset) static void view3d_draw_view(const bContext *C, ARegion *ar) { - ED_view3d_draw_setup_view(CTX_wm_window(C), CTX_data_scene(C), ar, CTX_wm_view3d(C), NULL, NULL, NULL); + ED_view3d_draw_setup_view(CTX_wm_window(C), C, CTX_data_scene(C), ar, CTX_wm_view3d(C), NULL, NULL, NULL); /* Only 100% compliant on new spec goes bellow */ DRW_draw_view(C); @@ -1897,7 +1903,7 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar) * \{ */ static void view3d_stereo3d_setup_offscreen( - Scene *scene, View3D *v3d, ARegion *ar, + EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, float winmat[4][4], const char *viewname) { /* update the viewport matrices with the new camera */ @@ -1906,24 +1912,24 @@ static void view3d_stereo3d_setup_offscreen( const bool is_left = STREQ(viewname, STEREO_LEFT_NAME); BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat); - view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL); + view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL); } else { /* SCE_VIEWS_FORMAT_MULTIVIEW */ float viewmat[4][4]; Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname); BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat); - view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL); + view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL); } } -void ED_view3d_draw_offscreen_init(Scene *scene, SceneLayer *sl, View3D *v3d) +void ED_view3d_draw_offscreen_init(EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d) { RenderEngineType *type = RE_engines_find(scene->r.engine); if (type->flag & RE_USE_LEGACY_PIPELINE) { /* shadow buffers, before we setup matrices */ if (draw_glsl_material(scene, sl, NULL, v3d, v3d->drawtype)) { - VP_deprecated_gpu_update_lamps_shadows_world(scene, v3d); + VP_deprecated_gpu_update_lamps_shadows_world(eval_ctx, scene, v3d); } } } @@ -1947,7 +1953,7 @@ static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar) * stuff like shadow buffers */ void ED_view3d_draw_offscreen( - Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int winx, int winy, + EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int winx, int winy, float viewmat[4][4], float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, const char *viewname, GPUFX *fx, GPUFXSettings *fx_settings, @@ -1996,9 +2002,9 @@ void ED_view3d_draw_offscreen( } if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera) - view3d_stereo3d_setup_offscreen(scene, v3d, ar, winmat, viewname); + view3d_stereo3d_setup_offscreen(eval_ctx, scene, v3d, ar, winmat, viewname); else - view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL); + view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL); /* main drawing call */ RenderEngineType *type = RE_engines_find(scene->r.engine); @@ -2067,7 +2073,7 @@ void ED_view3d_draw_offscreen( * (avoids re-creating when doing multiple GL renders). */ ImBuf *ED_view3d_draw_offscreen_imbuf( - Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int sizex, int sizey, + EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag, bool draw_background, int alpha_mode, int samples, bool full_samples, const char *viewname, /* output vars */ @@ -2096,7 +2102,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( } } - ED_view3d_draw_offscreen_init(scene, sl, v3d); + ED_view3d_draw_offscreen_init(eval_ctx, scene, sl, v3d); GPU_offscreen_bind(ofs, true); @@ -2138,7 +2144,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( if ((samples && full_samples) == 0) { /* Single-pass render, common case */ ED_view3d_draw_offscreen( - scene, sl, v3d, ar, sizex, sizey, NULL, winmat, + eval_ctx, scene, sl, v3d, ar, sizex, sizey, NULL, winmat, draw_background, draw_sky, !is_ortho, viewname, fx, &fx_settings, ofs); @@ -2162,7 +2168,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( /* first sample buffer, also initializes 'rv3d->persmat' */ ED_view3d_draw_offscreen( - scene, sl, v3d, ar, sizex, sizey, NULL, winmat, + eval_ctx, scene, sl, v3d, ar, sizex, sizey, NULL, winmat, draw_background, draw_sky, !is_ortho, viewname, fx, &fx_settings, ofs); GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp); @@ -2181,7 +2187,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( (jit_ofs[j][1] * 2.0f) / sizey); ED_view3d_draw_offscreen( - scene, sl, v3d, ar, sizex, sizey, NULL, winmat_jitter, + eval_ctx, scene, sl, v3d, ar, sizex, sizey, NULL, winmat_jitter, draw_background, draw_sky, !is_ortho, viewname, fx, &fx_settings, ofs); GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp); @@ -2232,7 +2238,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( * \note used by the sequencer */ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( - Scene *scene, SceneLayer *sl, Object *camera, int width, int height, + EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, Object *camera, int width, int height, unsigned int flag, int drawtype, bool use_solid_tex, bool use_gpencil, bool draw_background, int alpha_mode, int samples, bool full_samples, const char *viewname, GPUFX *fx, GPUOffScreen *ofs, char err_out[256]) @@ -2286,7 +2292,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( invert_m4_m4(rv3d.persinv, rv3d.viewinv); return ED_view3d_draw_offscreen_imbuf( - scene, sl, &v3d, &ar, width, height, flag, + eval_ctx, scene, sl, &v3d, &ar, width, height, flag, draw_background, alpha_mode, samples, full_samples, viewname, fx, ofs, err_out); } @@ -2335,9 +2341,13 @@ void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool drawfloor(scene, v3d, grid_unit, write_depth); } -void VP_legacy_view3d_main_region_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]) +void VP_legacy_view3d_main_region_setup_view(const bContext *C, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]) { - view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); + + view3d_main_region_setup_view(&eval_ctx, scene, v3d, ar, viewmat, winmat, NULL); } bool VP_legacy_view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d) @@ -2345,9 +2355,9 @@ bool VP_legacy_view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v return view3d_stereo3d_active(CTX_wm_window(C), scene, v3d, rv3d); } -void VP_legacy_view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar) +void VP_legacy_view3d_stereo3d_setup(const bContext *C, Scene *scene, View3D *v3d, ARegion *ar) { - view3d_stereo3d_setup(scene, v3d, ar, NULL); + view3d_stereo3d_setup(C, scene, v3d, ar, NULL); } bool VP_legacy_use_depth(Scene *scene, View3D *v3d) diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index a7ed6fcc30c..5c923d3c91b 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -70,6 +70,8 @@ #include "BKE_unit.h" #include "BKE_movieclip.h" +#include "DEG_depsgraph.h" + #include "RE_engine.h" #include "IMB_imbuf_types.h" @@ -211,7 +213,7 @@ static void draw_view_icon(RegionView3D *rv3d, rcti *rect) /* *********************** backdraw for selection *************** */ -static void backdrawview3d(Scene *scene, SceneLayer *sl, wmWindow *win, ARegion *ar, View3D *v3d) +static void backdrawview3d(const bContext *C, Scene *scene, SceneLayer *sl, wmWindow *win, ARegion *ar, View3D *v3d) { RegionView3D *rv3d = ar->regiondata; struct Base *base = sl->basact; @@ -312,7 +314,7 @@ static void backdrawview3d(Scene *scene, SceneLayer *sl, wmWindow *win, ARegion G.f |= G_BACKBUFSEL; if (base && ((base->flag & BASE_VISIBLED) != 0)) - draw_object_backbufsel(scene, v3d, rv3d, base->object); + draw_object_backbufsel(C, scene, v3d, rv3d, base->object); if (rv3d->gpuoffscreen) GPU_offscreen_unbind(rv3d->gpuoffscreen, true); @@ -353,10 +355,10 @@ static void view3d_opengl_read_Z_pixels(ARegion *ar, int x, int y, int w, int h, glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data); } -void ED_view3d_backbuf_validate(ViewContext *vc) +void ED_view3d_backbuf_validate(const bContext *C, ViewContext *vc) { if (vc->v3d->flag & V3D_INVALID_BACKBUF) - backdrawview3d(vc->scene, vc->scene_layer, vc->win, vc->ar, vc->v3d); + backdrawview3d(C, vc->scene, vc->scene_layer, vc->win, vc->ar, vc->v3d); } /** @@ -369,13 +371,13 @@ int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist) } /* samples a single pixel (copied from vpaint) */ -unsigned int ED_view3d_backbuf_sample(ViewContext *vc, int x, int y) +unsigned int ED_view3d_backbuf_sample(const bContext *C, ViewContext *vc, int x, int y) { if (x >= vc->ar->winx || y >= vc->ar->winy) { return 0; } - ED_view3d_backbuf_validate(vc); + ED_view3d_backbuf_validate(C, vc); unsigned int col; view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); @@ -389,7 +391,7 @@ unsigned int ED_view3d_backbuf_sample(ViewContext *vc, int x, int y) } /* reads full rect, converts indices */ -ImBuf *ED_view3d_backbuf_read(ViewContext *vc, int xmin, int ymin, int xmax, int ymax) +ImBuf *ED_view3d_backbuf_read(const bContext *C, ViewContext *vc, int xmin, int ymin, int xmax, int ymax) { /* clip */ const rcti clip = { @@ -407,7 +409,7 @@ ImBuf *ED_view3d_backbuf_read(ViewContext *vc, int xmin, int ymin, int xmax, int ImBuf *ibuf_clip = IMB_allocImBuf(size_clip[0], size_clip[1], 32, IB_rect); - ED_view3d_backbuf_validate(vc); + ED_view3d_backbuf_validate(C, vc); view3d_opengl_read_pixels(vc->ar, clip.xmin, clip.ymin, size_clip[0], size_clip[1], GL_RGBA, GL_UNSIGNED_BYTE, ibuf_clip->rect); @@ -446,7 +448,7 @@ ImBuf *ED_view3d_backbuf_read(ViewContext *vc, int xmin, int ymin, int xmax, int /* smart function to sample a rect spiralling outside, nice for backbuf selection */ unsigned int ED_view3d_backbuf_sample_rect( - ViewContext *vc, const int mval[2], int size, + const bContext *C, ViewContext *vc, const int mval[2], int size, unsigned int min, unsigned int max, float *r_dist) { int dirvec[4][2]; @@ -455,7 +457,7 @@ unsigned int ED_view3d_backbuf_sample_rect( const int minx = mval[0] - (amount + 1); const int miny = mval[1] - (amount + 1); - ImBuf *buf = ED_view3d_backbuf_read(vc, minx, miny, minx + size - 1, miny + size - 1); + ImBuf *buf = ED_view3d_backbuf_read(C, vc, minx, miny, minx + size - 1, miny + size - 1); if (!buf) return 0; unsigned index = 0; @@ -835,7 +837,7 @@ void ED_view3d_after_add(ListBase *lb, BaseLegacy *base, const short dflag) } /* disables write in zbuffer and draws it over */ -static void view3d_draw_transp(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d) +static void view3d_draw_transp(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d) { View3DAfter *v3da; @@ -843,7 +845,7 @@ static void view3d_draw_transp(Scene *scene, SceneLayer *sl, ARegion *ar, View3D v3d->transp = true; while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) { - draw_object(scene, sl, ar, v3d, v3da->base, v3da->dflag); + draw_object(C, scene, sl, ar, v3d, v3da->base, v3da->dflag); MEM_freeN(v3da); } v3d->transp = false; @@ -853,7 +855,7 @@ static void view3d_draw_transp(Scene *scene, SceneLayer *sl, ARegion *ar, View3D } /* clears zbuffer and draws it over */ -static void view3d_draw_xray(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, bool *clear) +static void view3d_draw_xray(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, bool *clear) { if (*clear && v3d->zbuf) { glClear(GL_DEPTH_BUFFER_BIT); @@ -863,7 +865,7 @@ static void view3d_draw_xray(Scene *scene, SceneLayer *sl, ARegion *ar, View3D * v3d->xray = true; View3DAfter *v3da; while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) { - draw_object(scene, sl, ar, v3d, v3da->base, v3da->dflag); + draw_object(C, scene, sl, ar, v3d, v3da->base, v3da->dflag); MEM_freeN(v3da); } v3d->xray = false; @@ -871,7 +873,7 @@ static void view3d_draw_xray(Scene *scene, SceneLayer *sl, ARegion *ar, View3D * /* clears zbuffer and draws it over */ -static void view3d_draw_xraytransp(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, const bool clear) +static void view3d_draw_xraytransp(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, const bool clear) { if (clear && v3d->zbuf) glClear(GL_DEPTH_BUFFER_BIT); @@ -883,7 +885,7 @@ static void view3d_draw_xraytransp(Scene *scene, SceneLayer *sl, ARegion *ar, Vi View3DAfter *v3da; while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) { - draw_object(scene, sl, ar, v3d, v3da->base, v3da->dflag); + draw_object(C, scene, sl, ar, v3d, v3da->base, v3da->dflag); MEM_freeN(v3da); } @@ -895,7 +897,7 @@ static void view3d_draw_xraytransp(Scene *scene, SceneLayer *sl, ARegion *ar, Vi /* clears zbuffer and draws it over, * note that in the select version we don't care about transparent flag as with regular drawing */ -static void view3d_draw_xray_select(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, bool *clear) +static void view3d_draw_xray_select(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, bool *clear) { /* Not ideal, but we need to read from the previous depths before clearing * otherwise we could have a function to load the depths after drawing. @@ -915,7 +917,7 @@ static void view3d_draw_xray_select(Scene *scene, SceneLayer *sl, ARegion *ar, V v3d->xray = true; while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) { if (GPU_select_load_id(v3da->base->object->select_color)) { - draw_object_select(scene, sl, ar, v3d, v3da->base, v3da->dflag); + draw_object_select(C, scene, sl, ar, v3d, v3da->base, v3da->dflag); } MEM_freeN(v3da); } @@ -951,7 +953,7 @@ static DupliObject *dupli_step(DupliObject *dob) } static void draw_dupli_objects_color( - Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base, + const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base, const short dflag, const int color) { RegionView3D *rv3d = ar->regiondata; @@ -965,6 +967,9 @@ static void draw_dupli_objects_color( char dt; short dtx; DupliApplyData *apply_data; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); if ((base->flag & BASE_VISIBLED) == 0) return; if ((base->object->restrictflag & OB_RESTRICT_RENDER) && (v3d->flag2 & V3D_RENDER_OVERRIDE)) return; @@ -981,7 +986,7 @@ static void draw_dupli_objects_color( lb = object_duplilist(G.main->eval_ctx, scene, base->object); // BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */ - apply_data = duplilist_apply(base->object, scene, lb); + apply_data = duplilist_apply(&eval_ctx, base->object, scene, lb); DupliObject *dob_next = NULL; DupliObject *dob = dupli_step(lb->first); @@ -1034,7 +1039,7 @@ static void draw_dupli_objects_color( if (!testbb || ED_view3d_boundbox_clip_ex(rv3d, &bb, dob->mat)) { copy_m4_m4(dob->ob->obmat, dob->mat); GPU_begin_dupli_object(dob); - draw_object(scene, sl, ar, v3d, &tbase, dflag_dupli); + draw_object(C, scene, sl, ar, v3d, &tbase, dflag_dupli); GPU_end_dupli_object(); } @@ -1052,7 +1057,7 @@ static void draw_dupli_objects_color( free_object_duplilist(lb); } -void draw_dupli_objects(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base) +void draw_dupli_objects(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base) { /* define the color here so draw_dupli_objects_color can be called * from the set loop */ @@ -1062,7 +1067,7 @@ void draw_dupli_objects(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, if (base->object->dup_group && base->object->dup_group->id.us < 1) color = TH_REDALERT; - draw_dupli_objects_color(scene, sl, ar, v3d, base, 0, color); + draw_dupli_objects_color(C, scene, sl, ar, v3d, base, 0, color); } /* XXX warning, not using gpu offscreen here */ @@ -1175,12 +1180,12 @@ float view3d_depth_near(ViewDepths *d) return far == far_real ? FLT_MAX : far; } -void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d) +void ED_view3d_draw_depth_gpencil(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d) { bool zbuf = v3d->zbuf; /* Setup view matrix. */ - ED_view3d_draw_setup_view(NULL, scene, ar, v3d, NULL, NULL, NULL); + ED_view3d_draw_setup_view(NULL, C, scene, ar, v3d, NULL, NULL, NULL); glClear(GL_DEPTH_BUFFER_BIT); @@ -1195,10 +1200,10 @@ void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d) if (!zbuf) glDisable(GL_DEPTH_TEST); } -void ED_view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d) +void ED_view3d_draw_depth_loop(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d) { Base *base; - SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene); + SceneLayer *sl = CTX_data_scene_layer(C); /* no need for color when drawing depth buffer */ const short dflag_depth = DRAW_CONSTCOLOR; @@ -1207,9 +1212,9 @@ void ED_view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d) Scene *sce_iter; for (SETLOOPER(scene->set, sce_iter, base)) { if ((base->flag & BASE_VISIBLED) != 0) { - draw_object(scene, sl, ar, v3d, base, 0); + draw_object(C, scene, sl, ar, v3d, base, 0); if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects_color(scene, sl, ar, v3d, base, dflag_depth, TH_UNDEFINED); + draw_dupli_objects_color(C, scene, sl, ar, v3d, base, dflag_depth, TH_UNDEFINED); } } } @@ -1219,9 +1224,9 @@ void ED_view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d) if ((base->flag & BASE_VISIBLED) != 0) { /* dupli drawing */ if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects_color(scene, sl, ar, v3d, base, dflag_depth, TH_UNDEFINED); + draw_dupli_objects_color(C, scene, sl, ar, v3d, base, dflag_depth, TH_UNDEFINED); } - draw_object(scene, sl, ar, v3d, base, dflag_depth); + draw_object(C, scene, sl, ar, v3d, base, dflag_depth); } } @@ -1242,7 +1247,7 @@ void ED_view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d) if (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first) { glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */ for (v3da = v3d->afterdraw_xray.first; v3da; v3da = v3da->next) { - draw_object(scene, sl, ar, v3d, v3da->base, dflag_depth); + draw_object(C, scene, sl, ar, v3d, v3da->base, dflag_depth); } glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */ } @@ -1251,21 +1256,21 @@ void ED_view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d) v3d->xray = false; v3d->transp = true; while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) { - draw_object(scene, sl, ar, v3d, v3da->base, dflag_depth); + draw_object(C, scene, sl, ar, v3d, v3da->base, dflag_depth); MEM_freeN(v3da); } v3d->xray = true; v3d->transp = false; while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) { - draw_object(scene, sl, ar, v3d, v3da->base, dflag_depth); + draw_object(C, scene, sl, ar, v3d, v3da->base, dflag_depth); MEM_freeN(v3da); } v3d->xray = true; v3d->transp = true; while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) { - draw_object(scene, sl, ar, v3d, v3da->base, dflag_depth); + draw_object(C, scene, sl, ar, v3d, v3da->base, dflag_depth); MEM_freeN(v3da); } @@ -1278,19 +1283,19 @@ void ED_view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d) } void ED_view3d_draw_select_loop( - ViewContext *vc, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, + const bContext *C, ViewContext *vc, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, bool use_obedit_skip, bool use_nearest) { short code = 1; const short dflag = DRAW_PICKING | DRAW_CONSTCOLOR; if (vc->obedit && vc->obedit->type == OB_MBALL) { - draw_object(scene, sl, ar, v3d, BASACT_NEW, dflag); + draw_object(C, scene, sl, ar, v3d, BASACT_NEW, dflag); } else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) { /* if not drawing sketch, draw bones */ if (!BDR_drawSketchNames(vc)) { - draw_object(scene, sl, ar, v3d, BASACT_NEW, dflag); + draw_object(C, scene, sl, ar, v3d, BASACT_NEW, dflag); } } else { @@ -1311,7 +1316,7 @@ void ED_view3d_draw_select_loop( } else { if (GPU_select_load_id(code)) { - draw_object(scene, sl, ar, v3d, base, dflag); + draw_object(C, scene, sl, ar, v3d, base, dflag); } } code++; @@ -1322,7 +1327,7 @@ void ED_view3d_draw_select_loop( if (use_nearest) { bool xrayclear = true; if (v3d->afterdraw_xray.first) { - view3d_draw_xray_select(scene, sl, ar, v3d, &xrayclear); + view3d_draw_xray_select(C, scene, sl, ar, v3d, &xrayclear); } } } @@ -1362,7 +1367,7 @@ static void gpu_render_lamp_update(Scene *scene, View3D *v3d, } } -static void gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d) +static void gpu_update_lamps_shadows_world(EvaluationContext *eval_ctx, Scene *scene, View3D *v3d) { ListBase shadows; Scene *sce_iter; @@ -1422,7 +1427,7 @@ static void gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d) /* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */ ED_view3d_draw_offscreen( - scene, BKE_scene_layer_context_active_PLACEHOLDER(scene), v3d, &ar, winsize, winsize, viewmat, winmat, + eval_ctx, scene, eval_ctx->scene_layer, v3d, &ar, winsize, winsize, viewmat, winmat, false, false, true, NULL, NULL, NULL, NULL); GPU_lamp_shadow_buffer_unbind(shadow->lamp); @@ -1558,10 +1563,10 @@ static void view3d_draw_objects( for (SETLOOPER(scene->set, sce_iter, base)) { if ((base->flag & BASE_VISIBLED) != 0) { UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f); - draw_object(scene, sl, ar, v3d, base, dflag); + draw_object(C, scene, sl, ar, v3d, base, dflag); if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects_color(scene, sl, ar, v3d, base, dflag, TH_UNDEFINED); + draw_dupli_objects_color(C, scene, sl, ar, v3d, base, dflag, TH_UNDEFINED); } } } @@ -1574,9 +1579,9 @@ static void view3d_draw_objects( if ((base->flag & BASE_VISIBLED) != 0) { /* dupli drawing */ if (base->object->transflag & OB_DUPLI) - draw_dupli_objects(scene, sl, ar, v3d, base); + draw_dupli_objects(C, scene, sl, ar, v3d, base); - draw_object(scene, sl, ar, v3d, base, 0); + draw_object(C, scene, sl, ar, v3d, base, 0); } } } @@ -1591,11 +1596,11 @@ static void view3d_draw_objects( /* dupli drawing */ if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects(scene, sl, ar, v3d, base); + draw_dupli_objects(C, scene, sl, ar, v3d, base); } if ((base->flag & BASE_SELECTED) == 0) { if (base->object != scene->obedit) - draw_object(scene, sl, ar, v3d, base, 0); + draw_object(C, scene, sl, ar, v3d, base, 0); } } } @@ -1607,7 +1612,7 @@ static void view3d_draw_objects( for (base = sl->object_bases.first; base; base = base->next) { if ((base->flag & BASE_VISIBLED) != 0) { if (base->object == scene->obedit || (base->flag & BASE_SELECTED)) { - draw_object(scene, sl, ar, v3d, base, 0); + draw_object(C, scene, sl, ar, v3d, base, 0); } } } @@ -1629,7 +1634,7 @@ static void view3d_draw_objects( } /* transp and X-ray afterdraw stuff */ - if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, sl, ar, v3d); + if (v3d->afterdraw_transp.first) view3d_draw_transp(C, scene, sl, ar, v3d); /* always do that here to cleanup depth buffers if none needed */ if (fx) { @@ -1637,8 +1642,8 @@ static void view3d_draw_objects( GPU_fx_compositor_setup_XRay_pass(fx, do_composite_xray); } - if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, sl, ar, v3d, &xrayclear); - if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, sl, ar, v3d, xrayclear); + if (v3d->afterdraw_xray.first) view3d_draw_xray(C, scene, sl, ar, v3d, &xrayclear); + if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(C, scene, sl, ar, v3d, xrayclear); if (fx && do_composite_xray) { GPU_fx_compositor_XRay_resolve(fx); @@ -1846,7 +1851,7 @@ static bool view3d_main_region_draw_engine(const bContext *C, Scene *scene, } /* setup view matrices */ - VP_legacy_view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL); + VP_legacy_view3d_main_region_setup_view(C, scene, v3d, ar, NULL, NULL); /* background draw */ ED_region_pixelspace(ar); @@ -1930,15 +1935,18 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Sce ARegion *ar, const char **grid_unit) { wmWindow *win = CTX_wm_window(C); + EvaluationContext eval_ctx; RegionView3D *rv3d = ar->regiondata; unsigned int lay_used = v3d->lay_used; + CTX_data_eval_ctx(C, &eval_ctx); + /* post processing */ bool do_compositing = false; /* shadow buffers, before we setup matrices */ if (draw_glsl_material(scene, sl, NULL, v3d, v3d->drawtype)) - gpu_update_lamps_shadows_world(scene, v3d); + gpu_update_lamps_shadows_world(&eval_ctx, scene, v3d); /* reset default OpenGL lights if needed (i.e. after preferences have been altered) */ if (rv3d->rflag & RV3D_GPULIGHT_UPDATE) { @@ -1948,9 +1956,9 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Sce /* setup the view matrix */ if (VP_legacy_view3d_stereo3d_active(C, scene, v3d, rv3d)) - VP_legacy_view3d_stereo3d_setup(scene, v3d, ar); + VP_legacy_view3d_stereo3d_setup(C, scene, v3d, ar); else - VP_legacy_view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL); + VP_legacy_view3d_main_region_setup_view(C, scene, v3d, ar, NULL, NULL); rv3d->rflag &= ~RV3D_IS_GAME_ENGINE; #ifdef WITH_GAMEENGINE @@ -2113,13 +2121,13 @@ void view3d_main_region_draw_legacy(const bContext *C, ARegion *ar) if (v3d->drawtype == OB_RENDER) view3d_main_region_draw_engine(C, scene, ar, v3d, clip_border, &border_rect); - VP_legacy_view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL); + VP_legacy_view3d_main_region_setup_view(C, scene, v3d, ar, NULL, NULL); glClear(GL_DEPTH_BUFFER_BIT); - WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_2D); - ED_region_pixelspace(ar); + WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_2D); + view3d_main_region_draw_info(C, scene, ar, v3d, grid_unit, render_border); gpuPopProjectionMatrix(); @@ -2152,9 +2160,9 @@ void VP_deprecated_view3d_draw_objects( view3d_draw_objects(C, scene, v3d, ar, grid_unit, do_bgpic, draw_offscreen, fx); } -void VP_deprecated_gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d) +void VP_deprecated_gpu_update_lamps_shadows_world(EvaluationContext *eval_ctx, Scene *scene, View3D *v3d) { - gpu_update_lamps_shadows_world(scene, v3d); + gpu_update_lamps_shadows_world(eval_ctx, scene, v3d); } /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 8bb0619c45b..0350a67f3d4 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -745,7 +745,7 @@ static void viewops_data_create_ex( negate_v3_v3(fallback_depth_pt, rv3d->ofs); vod->use_dyn_ofs = ED_view3d_autodist( - graph, vod->ar, vod->v3d, + C, graph, vod->ar, vod->v3d, event->mval, vod->dyn_ofs, true, fallback_depth_pt); } else { @@ -3069,6 +3069,8 @@ static int viewselected_exec(bContext *C, wmOperator *op) SceneLayer *sl = CTX_data_scene_layer(C); bGPdata *gpd = CTX_data_gpencil_data(C); const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE)); + const bool is_face_map = ((is_gp_edit == false) && ar->manipulator_map && + WM_manipulatormap_is_any_selected(ar->manipulator_map)); Object *ob = OBACT_NEW; Object *obedit = CTX_data_edit_object(C); float min[3], max[3]; @@ -3080,8 +3082,7 @@ static int viewselected_exec(bContext *C, wmOperator *op) const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); INIT_MINMAX(min, max); - - if (is_gp_edit) { + if (is_gp_edit || is_face_map) { ob = NULL; } @@ -3113,6 +3114,9 @@ static int viewselected_exec(bContext *C, wmOperator *op) } CTX_DATA_END; } + else if (is_face_map) { + ok = WM_manipulatormap_minmax(ar->manipulator_map, true, true, min, max); + } else if (obedit) { ok = ED_view3d_minmax_verts(obedit, min, max); /* only selected */ } @@ -3324,7 +3328,7 @@ static int viewcenter_pick_invoke(bContext *C, wmOperator *op, const wmEvent *ev view3d_operator_needs_opengl(C); - if (ED_view3d_autodist(graph, ar, v3d, event->mval, new_ofs, false, NULL)) { + if (ED_view3d_autodist(C, graph, ar, v3d, event->mval, new_ofs, false, NULL)) { /* pass */ } else { @@ -3610,7 +3614,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) ED_view3d_dist_range_get(v3d, dist_range); /* Get Z Depths, needed for perspective, nice for ortho */ - ED_view3d_draw_depth(CTX_data_depsgraph(C), ar, v3d, true); + ED_view3d_draw_depth(C, CTX_data_depsgraph(C), ar, v3d, true); { /* avoid allocating the whole depth buffer */ @@ -4712,7 +4716,7 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2]) if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */ struct Depsgraph *graph = CTX_data_depsgraph(C); view3d_operator_needs_opengl(C); - if (ED_view3d_autodist(graph, ar, v3d, mval, fp, true, NULL)) { + if (ED_view3d_autodist(C, graph, ar, v3d, mval, fp, true, NULL)) { depth_used = true; } } @@ -4741,13 +4745,20 @@ void ED_view3d_cursor3d_update(bContext *C, const int mval[2]) ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = ar->regiondata; - float co_curr[2], co_prev[2]; + if (U.uiflag & USER_LOCK_CURSOR_ADJUST) { - if ((ED_view3d_project_float_global(ar, fp_prev, co_prev, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && - (ED_view3d_project_float_global(ar, fp_curr, co_curr, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) - { - rv3d->ofs_lock[0] += (co_curr[0] - co_prev[0]) / (ar->winx * 0.5f); - rv3d->ofs_lock[1] += (co_curr[1] - co_prev[1]) / (ar->winy * 0.5f); + float co_curr[2], co_prev[2]; + + if ((ED_view3d_project_float_global(ar, fp_prev, co_prev, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_float_global(ar, fp_curr, co_curr, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) + { + rv3d->ofs_lock[0] += (co_curr[0] - co_prev[0]) / (ar->winx * 0.5f); + rv3d->ofs_lock[1] += (co_curr[1] - co_prev[1]) / (ar->winy * 0.5f); + } + } + else { + /* Cursor may be outside of the view, prevent it getting 'lost', see: T40353 & T45301 */ + zero_v2(rv3d->ofs_lock); } } @@ -4889,7 +4900,7 @@ static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int marg * \param fallback_depth_pt: Use this points depth when no depth can be found. */ bool ED_view3d_autodist( - struct Depsgraph *graph, ARegion *ar, View3D *v3d, + const bContext *C, struct Depsgraph *graph, ARegion *ar, View3D *v3d, const int mval[2], float mouse_worldloc[3], const bool alphaoverride, const float fallback_depth_pt[3]) { @@ -4899,7 +4910,7 @@ bool ED_view3d_autodist( bool depth_ok = false; /* Get Z Depths, needed for perspective, nice for ortho */ - ED_view3d_draw_depth(graph, ar, v3d, alphaoverride); + ED_view3d_draw_depth(C, graph, ar, v3d, alphaoverride); /* Attempt with low margin's first */ i = 0; @@ -4928,18 +4939,18 @@ bool ED_view3d_autodist( } void ED_view3d_autodist_init( - struct Depsgraph *graph, + const bContext *C, struct Depsgraph *graph, ARegion *ar, View3D *v3d, int mode) { /* Get Z Depths, needed for perspective, nice for ortho */ switch (mode) { case 0: - ED_view3d_draw_depth(graph, ar, v3d, true); + ED_view3d_draw_depth(C, graph, ar, v3d, true); break; case 1: { Scene *scene = DEG_get_evaluated_scene(graph); - ED_view3d_draw_depth_gpencil(scene, ar, v3d); + ED_view3d_draw_depth_gpencil(C, scene, ar, v3d); break; } } @@ -5144,6 +5155,7 @@ void ED_view3d_from_object(Object *ob, float ofs[3], float quat[4], float *dist, void ED_view3d_to_object(Object *ob, const float ofs[3], const float quat[4], const float dist) { float mat[4][4]; + ED_view3d_to_m4(mat, ofs, quat, dist); BKE_object_apply_mat4(ob, mat, true, true); } diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index 85f44b528bc..bce27fc5c92 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -417,7 +417,7 @@ static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent } fly->v3d_camera_control = ED_view3d_cameracontrol_acquire( - fly->scene, fly->v3d, fly->rv3d, + C, fly->scene, fly->v3d, fly->rv3d, (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0); /* calculate center */ diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index b3b40b5eb83..49c38b9a0f7 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -146,14 +146,14 @@ void draw_motion_paths_cleanup(View3D *v3d); /* drawobject.c */ -void draw_object(Scene *scene, struct SceneLayer *sl, struct ARegion *ar, View3D *v3d, BaseLegacy *base, const short dflag); -void draw_object_select(Scene *scene, struct SceneLayer *sl, struct ARegion *ar, View3D *v3d, Base *base, const short dflag); +void draw_object(const struct bContext *C, Scene *scene, struct SceneLayer *sl, struct ARegion *ar, View3D *v3d, BaseLegacy *base, const short dflag); +void draw_object_select(const struct bContext *C, Scene *scene, struct SceneLayer *sl, struct ARegion *ar, View3D *v3d, Base *base, const short dflag); void draw_mesh_object_outline(View3D *v3d, Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]); bool draw_glsl_material(Scene *scene, struct SceneLayer *sl, struct Object *ob, View3D *v3d, const char dt); -void draw_object_instance(Scene *scene, struct SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline, const float wire_col[4]); -void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob); +void draw_object_instance(const struct bContext *C, Scene *scene, struct SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline, const float wire_col[4]); +void draw_object_backbufsel(const struct bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob); void draw_object_wire_color(Scene *scene, struct SceneLayer *, Base *base, unsigned char r_ob_wire_col[4]); void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4]); @@ -185,7 +185,7 @@ enum { int view3d_effective_drawtype(const struct View3D *v3d); /* drawarmature.c */ -bool draw_armature(Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base, +bool draw_armature(const struct bContext *C, Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base, const short dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_outline); @@ -217,18 +217,18 @@ void view3d_main_region_draw(const struct bContext *C, struct ARegion *ar); void view3d_draw_region_info(const struct bContext *C, struct ARegion *ar, const int offset); void ED_view3d_draw_depth( - struct Depsgraph *graph, + const struct bContext *C, struct Depsgraph *graph, struct ARegion *ar, View3D *v3d, bool alphaoverride); /* view3d_draw_legacy.c */ void view3d_main_region_draw_legacy(const struct bContext *C, struct ARegion *ar); -void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d); +void ED_view3d_draw_depth_gpencil(const struct bContext *C, Scene *scene, ARegion *ar, View3D *v3d); void ED_view3d_draw_select_loop( - ViewContext *vc, Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar, + const struct bContext *C, ViewContext *vc, Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar, bool use_obedit_skip, bool use_nearest); -void ED_view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d); +void ED_view3d_draw_depth_loop(const struct bContext *C, Scene *scene, ARegion *ar, View3D *v3d); void ED_view3d_after_add(ListBase *lb, BaseLegacy *base, const short dflag); @@ -274,7 +274,7 @@ void ED_view3d_smooth_view_force_finish( struct View3D *v3d, struct ARegion *ar); void view3d_winmatrix_set(ARegion *ar, const View3D *v3d, const rcti *rect); -void view3d_viewmatrix_set(Scene *scene, const View3D *v3d, RegionView3D *rv3d); +void view3d_viewmatrix_set(struct EvaluationContext *eval_ctx, Scene *scene, const View3D *v3d, RegionView3D *rv3d); void fly_modal_keymap(struct wmKeyConfig *keyconf); void walk_modal_keymap(struct wmKeyConfig *keyconf); @@ -289,7 +289,7 @@ void view3d_buttons_register(struct ARegionType *art); /* view3d_camera_control.c */ struct View3DCameraControl *ED_view3d_cameracontrol_acquire( - Scene *scene, View3D *v3d, RegionView3D *rv3d, + const struct bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d, const bool use_parent_root); void ED_view3d_cameracontrol_update( struct View3DCameraControl *vctrl, @@ -324,8 +324,11 @@ ARegion *view3d_has_tools_region(ScrArea *sa); extern const char *view3d_context_dir[]; /* doc access */ /* view3d_widgets.c */ -void VIEW3D_WGT_lamp (struct wmManipulatorGroupType *wgt); +void VIEW3D_WGT_lamp_spot (struct wmManipulatorGroupType *wgt); +void VIEW3D_WGT_lamp_area (struct wmManipulatorGroupType *wgt); +void VIEW3D_WGT_lamp_target (struct wmManipulatorGroupType *wgt); void VIEW3D_WGT_camera (struct wmManipulatorGroupType *wgt); +void VIEW3D_WGT_camera_view (struct wmManipulatorGroupType *wgt); void VIEW3D_WGT_force_field (struct wmManipulatorGroupType *wgt); void VIEW3D_WGT_armature_facemaps(struct wmManipulatorGroupType *wgt); @@ -354,10 +357,10 @@ void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect); void VP_legacy_draw_selected_name(Scene *scene, Object *ob, rcti *rect); void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit); void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth); -void VP_legacy_view3d_main_region_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]); +void VP_legacy_view3d_main_region_setup_view(const struct bContext *C, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]); bool VP_legacy_view3d_stereo3d_active(const struct bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d); -void VP_legacy_view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar); -void draw_dupli_objects(Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base); +void VP_legacy_view3d_stereo3d_setup(const struct bContext *C, Scene *scene, View3D *v3d, ARegion *ar); +void draw_dupli_objects(const struct bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base); bool VP_legacy_use_depth(Scene *scene, View3D *v3d); void VP_drawviewborder(Scene *scene, ARegion *ar, View3D *v3d); void VP_drawrenderborder(ARegion *ar, View3D *v3d); @@ -366,7 +369,7 @@ void VP_view3d_draw_background_world(Scene *scene, View3D *v3d, RegionView3D *rv void VP_view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar); /* temporary legacy calls, only when there is a switch between new/old draw calls */ -void VP_deprecated_gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d); +void VP_deprecated_gpu_update_lamps_shadows_world(struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d); void VP_deprecated_view3d_draw_objects( const struct bContext *C, Scene *scene, View3D *v3d, ARegion *ar, diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index ef7b01f7a21..48dd3d64e86 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -40,6 +40,9 @@ #include "BKE_DerivedMesh.h" #include "BKE_displist.h" #include "BKE_editmesh.h" +#include "BKE_context.h" + +#include "DEG_depsgraph.h" #include "bmesh.h" @@ -104,12 +107,17 @@ static void meshobject_foreachScreenVert__mapFunc(void *userData, int index, con } void meshobject_foreachScreenVert( - ViewContext *vc, + const bContext *C, ViewContext *vc, void (*func)(void *userData, MVert *eve, const float screen_co[2], int index), void *userData, eV3DProjTest clip_flag) { foreachScreenObjectVert_userData data; - DerivedMesh *dm = mesh_get_derived_deform(vc->scene, vc->obact, CD_MASK_BAREMESH); + EvaluationContext eval_ctx; + DerivedMesh *dm; + + CTX_data_eval_ctx(C, &eval_ctx); + + dm = mesh_get_derived_deform(&eval_ctx, vc->scene, vc->obact, CD_MASK_BAREMESH); ED_view3d_check_mats_rv3d(vc->rv3d); @@ -145,12 +153,17 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const flo } void mesh_foreachScreenVert( - ViewContext *vc, + const bContext *C, ViewContext *vc, void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index), void *userData, eV3DProjTest clip_flag) { foreachScreenVert_userData data; - DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); + EvaluationContext eval_ctx; + DerivedMesh *dm; + + CTX_data_eval_ctx(C, &eval_ctx); + + dm = editbmesh_get_derived_cage(&eval_ctx, vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); ED_view3d_check_mats_rv3d(vc->rv3d); @@ -199,12 +212,17 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo } void mesh_foreachScreenEdge( - ViewContext *vc, + const bContext *C, ViewContext *vc, void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), void *userData, eV3DProjTest clip_flag) { foreachScreenEdge_userData data; - DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); + EvaluationContext eval_ctx; + DerivedMesh *dm; + + CTX_data_eval_ctx(C, &eval_ctx); + + dm = editbmesh_get_derived_cage(&eval_ctx, vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); ED_view3d_check_mats_rv3d(vc->rv3d); @@ -245,12 +263,17 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo } void mesh_foreachScreenFace( - ViewContext *vc, + const bContext *C, ViewContext *vc, void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index), void *userData, const eV3DProjTest clip_flag) { foreachScreenFace_userData data; - DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); + EvaluationContext eval_ctx; + DerivedMesh *dm; + + CTX_data_eval_ctx(C, &eval_ctx); + + dm = editbmesh_get_derived_cage(&eval_ctx, vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); ED_view3d_check_mats_rv3d(vc->rv3d); diff --git a/source/blender/editors/space_view3d/view3d_manipulator_camera.c b/source/blender/editors/space_view3d/view3d_manipulator_camera.c new file mode 100644 index 00000000000..51467775298 --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_manipulator_camera.c @@ -0,0 +1,412 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_view3d/view3d_manipulator_camera.c + * \ingroup spview3d + */ + + +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_camera.h" +#include "BKE_context.h" + +#include "DNA_object_types.h" +#include "DNA_camera_types.h" + +#include "ED_armature.h" +#include "ED_screen.h" +#include "ED_manipulator_library.h" + +#include "MEM_guardedalloc.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "view3d_intern.h" /* own include */ + + +/* -------------------------------------------------------------------- */ + +/** \name Camera Manipulators + * \{ */ + +struct CameraWidgetGroup { + wmManipulator *dop_dist; + wmManipulator *focal_len; + wmManipulator *ortho_scale; +}; + +static bool WIDGETGROUP_camera_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) +{ + Object *ob = CTX_data_active_object(C); + + return (ob && ob->type == OB_CAMERA); +} + +static void cameragroup_property_setup(wmManipulator *widget, Object *ob, Camera *ca, const bool is_ortho) +{ + const float scale[3] = {1.0f / len_v3(ob->obmat[0]), 1.0f / len_v3(ob->obmat[1]), 1.0f / len_v3(ob->obmat[2])}; + const float scale_fac = ca->drawsize; + const float drawsize = is_ortho ? + (0.5f * ca->ortho_scale) : + (scale_fac / ((scale[0] + scale[1] + scale[2]) / 3.0f)); + const float half_sensor = 0.5f * ((ca->sensor_fit == CAMERA_SENSOR_FIT_VERT) ? ca->sensor_y : ca->sensor_x); + const char *propname = is_ortho ? "ortho_scale" : "lens"; + + PointerRNA camera_ptr; + float min, max, range; + float step, precision; + + RNA_pointer_create(&ca->id, &RNA_Camera, ca, &camera_ptr); + + /* get property range */ + PropertyRNA *prop = RNA_struct_find_property(&camera_ptr, propname); + RNA_property_float_ui_range(&camera_ptr, prop, &min, &max, &step, &precision); + range = max - min; + + ED_manipulator_arrow3d_set_range_fac(widget, is_ortho ? (scale_fac * range) : (drawsize * range / half_sensor)); +} + +static void WIDGETGROUP_camera_setup(const bContext *C, wmManipulatorGroup *mgroup) +{ + Object *ob = CTX_data_active_object(C); + Camera *ca = ob->data; + float dir[3]; + + const wmManipulatorType *wt_arrow = WM_manipulatortype_find("MANIPULATOR_WT_arrow_3d", true); + + struct CameraWidgetGroup *camgroup = MEM_callocN(sizeof(struct CameraWidgetGroup), __func__); + mgroup->customdata = camgroup; + + negate_v3_v3(dir, ob->obmat[2]); + + /* dof distance */ + { + wmManipulator *mpr; + const float color[4] = {1.0f, 0.3f, 0.0f, 1.0f}; + const float color_hi[4] = {1.0f, 0.3f, 0.0f, 1.0f}; + + mpr = camgroup->dop_dist = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); + RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CROSS); + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_HOVER, true); + WM_manipulator_set_color(mpr, color); + WM_manipulator_set_color_highlight(mpr, color_hi); + } + + /* focal length + * - logic/calculations are similar to BKE_camera_view_frame_ex, better keep in sync */ + { + wmManipulator *mpr; + const float color[4] = {1.0f, 1.0, 0.27f, 0.5f}; + const float color_hi[4] = {1.0f, 1.0, 0.27f, 1.0f}; + + mpr = camgroup->focal_len = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); + RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE); + RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED); + + WM_manipulator_set_color(mpr, color); + WM_manipulator_set_color_highlight(mpr, color_hi); + cameragroup_property_setup(mpr, ob, ca, false); + + mpr = camgroup->ortho_scale = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); + RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE); + RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED); + + WM_manipulator_set_color(mpr, color); + WM_manipulator_set_color_highlight(mpr, color_hi); + cameragroup_property_setup(mpr, ob, ca, true); + } +} + +static void WIDGETGROUP_camera_refresh(const bContext *C, wmManipulatorGroup *mgroup) +{ + if (!mgroup->customdata) + return; + + struct CameraWidgetGroup *camgroup = mgroup->customdata; + Object *ob = CTX_data_active_object(C); + Camera *ca = ob->data; + PointerRNA camera_ptr; + float dir[3]; + + RNA_pointer_create(&ca->id, &RNA_Camera, ca, &camera_ptr); + + negate_v3_v3(dir, ob->obmat[2]); + + if (ca->flag & CAM_SHOWLIMITS) { + WM_manipulator_set_matrix_location(camgroup->dop_dist, ob->obmat[3]); + WM_manipulator_set_matrix_rotation_from_yz_axis(camgroup->dop_dist, ob->obmat[1], dir); + WM_manipulator_set_scale(camgroup->dop_dist, ca->drawsize); + WM_manipulator_set_flag(camgroup->dop_dist, WM_MANIPULATOR_HIDDEN, false); + + /* need to set property here for undo. TODO would prefer to do this in _init */ + WM_manipulator_target_property_def_rna(camgroup->dop_dist, "offset", &camera_ptr, "dof_distance", -1); + } + else { + WM_manipulator_set_flag(camgroup->dop_dist, WM_MANIPULATOR_HIDDEN, true); + } + + /* TODO - make focal length/ortho scale widget optional */ + if (true) { + const bool is_ortho = (ca->type == CAM_ORTHO); + const float scale[3] = {1.0f / len_v3(ob->obmat[0]), 1.0f / len_v3(ob->obmat[1]), 1.0f / len_v3(ob->obmat[2])}; + const float scale_fac = ca->drawsize; + const float drawsize = is_ortho ? + (0.5f * ca->ortho_scale) : + (scale_fac / ((scale[0] + scale[1] + scale[2]) / 3.0f)); + float offset[3]; + float aspect[2]; + + wmManipulator *widget = is_ortho ? camgroup->ortho_scale : camgroup->focal_len; + WM_manipulator_set_flag(widget, WM_MANIPULATOR_HIDDEN, false); + WM_manipulator_set_flag(is_ortho ? camgroup->focal_len : camgroup->ortho_scale, WM_MANIPULATOR_HIDDEN, true); + + + /* account for lens shifting */ + offset[0] = ((ob->size[0] > 0.0f) ? -2.0f : 2.0f) * ca->shiftx; + offset[1] = 2.0f * ca->shifty; + offset[2] = 0.0f; + + /* get aspect */ + const Scene *scene = CTX_data_scene(C); + const float aspx = (float)scene->r.xsch * scene->r.xasp; + const float aspy = (float)scene->r.ysch * scene->r.yasp; + const int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, aspx, aspy); + aspect[0] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? 1.0f : aspx / aspy; + aspect[1] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? aspy / aspx : 1.0f; + + WM_manipulator_set_matrix_location(widget, ob->obmat[3]); + WM_manipulator_set_matrix_rotation_from_yz_axis(widget, ob->obmat[1], dir); + + RNA_float_set_array(widget->ptr, "aspect", aspect); + + WM_manipulator_set_matrix_offset_location(widget, offset); + WM_manipulator_set_scale(widget, drawsize); + + /* need to set property here for undo. TODO would prefer to do this in _init */ + WM_manipulator_target_property_def_rna(camgroup->focal_len, "offset", &camera_ptr, "lens", -1); + WM_manipulator_target_property_def_rna(camgroup->ortho_scale, "offset", &camera_ptr, "ortho_scale", -1); + } +} + +void VIEW3D_WGT_camera(wmManipulatorGroupType *wgt) +{ + wgt->name = "Camera Widgets"; + wgt->idname = "VIEW3D_WGT_camera"; + + wgt->flag = (WM_MANIPULATORGROUPTYPE_PERSISTENT | + WM_MANIPULATORGROUPTYPE_3D | + WM_MANIPULATORGROUPTYPE_SCALE | + WM_MANIPULATORGROUPTYPE_DEPTH_3D); + + wgt->poll = WIDGETGROUP_camera_poll; + wgt->setup = WIDGETGROUP_camera_setup; + wgt->refresh = WIDGETGROUP_camera_refresh; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ + +/** \name CameraView Manipulators + * \{ */ + +struct CameraViewWidgetGroup { + wmManipulator *border; + + struct { + rctf *edit_border; + rctf view_border; + } state; +}; + +/* scale callbacks */ +static void manipulator_render_border_prop_size_get( + const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop, + void *value_p) +{ + float *value = value_p; + BLI_assert(mpr_prop->type->array_length == 2); + struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data; + const rctf *border = viewgroup->state.edit_border; + + value[0] = BLI_rctf_size_x(border); + value[1] = BLI_rctf_size_y(border); +} + +static void manipulator_render_border_prop_size_set( + const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop, + const void *value_p) +{ + const float *value = value_p; + struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data; + rctf *border = viewgroup->state.edit_border; + BLI_assert(mpr_prop->type->array_length == 2); + + BLI_rctf_resize(border, value[0], value[1]); + BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, border, border); +} + +/* offset callbacks */ +static void manipulator_render_border_prop_offset_get( + const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop, + void *value_p) +{ + float *value = value_p; + BLI_assert(mpr_prop->type->array_length == 2); + struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data; + const rctf *border = viewgroup->state.edit_border; + + value[0] = BLI_rctf_cent_x(border); + value[1] = BLI_rctf_cent_y(border); +} + +static void manipulator_render_border_prop_offset_set( + const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop, + const void *value_p) +{ + const float *value = value_p; + struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data; + rctf *border = viewgroup->state.edit_border; + + BLI_assert(mpr_prop->type->array_length == 2); + + BLI_rctf_recenter(border, value[0], value[1]); + BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, border, border); +} + +static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) +{ + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; + Scene *scene = CTX_data_scene(C); + View3D *v3d = CTX_wm_view3d(C); + + if (rv3d->persp == RV3D_CAMOB) { + if (scene->r.mode & R_BORDER) { + return true; + } + } + else if (v3d->flag2 & V3D_RENDER_BORDER) { + return true; + } + return false; +} + +static void WIDGETGROUP_camera_view_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) +{ + struct CameraViewWidgetGroup *viewgroup = MEM_mallocN(sizeof(struct CameraViewWidgetGroup), __func__); + + viewgroup->border = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL); + + RNA_enum_set(viewgroup->border->ptr, "transform", + ED_MANIPULATOR_RECT_TRANSFORM_FLAG_TRANSLATE | ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE); + + mgroup->customdata = viewgroup; +} + +static void WIDGETGROUP_camera_view_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup) +{ + struct CameraViewWidgetGroup *viewgroup = mgroup->customdata; + + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; + if (rv3d->persp == RV3D_CAMOB) { + Scene *scene = CTX_data_scene(C); + View3D *v3d = CTX_wm_view3d(C); + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewgroup->state.view_border, false); + } + else { + viewgroup->state.view_border = (rctf){.xmin = 0, .ymin = 0, .xmax = ar->winx, .ymax = ar->winy}; + } + + wmManipulator *mpr = viewgroup->border; + unit_m4(mpr->matrix_space); + mul_v3_fl(mpr->matrix_space[0], BLI_rctf_size_x(&viewgroup->state.view_border)); + mul_v3_fl(mpr->matrix_space[1], BLI_rctf_size_y(&viewgroup->state.view_border)); + mpr->matrix_space[3][0] = viewgroup->state.view_border.xmin; + mpr->matrix_space[3][1] = viewgroup->state.view_border.ymin; +} + +static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmManipulatorGroup *mgroup) +{ + struct CameraViewWidgetGroup *viewgroup = mgroup->customdata; + + View3D *v3d = CTX_wm_view3d(C); + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; + Scene *scene = CTX_data_scene(C); + + { + wmManipulator *mpr = viewgroup->border; + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, false); + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_HOVER, true); + + RNA_enum_set(viewgroup->border->ptr, "transform", + ED_MANIPULATOR_RECT_TRANSFORM_FLAG_TRANSLATE | ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE); + + if (rv3d->persp == RV3D_CAMOB) { + viewgroup->state.edit_border = &scene->r.border; + } + else { + viewgroup->state.edit_border = &v3d->render_border; + } + + WM_manipulator_target_property_def_func( + mpr, "offset", + &(const struct wmManipulatorPropertyFnParams) { + .value_get_fn = manipulator_render_border_prop_offset_get, + .value_set_fn = manipulator_render_border_prop_offset_set, + .range_get_fn = NULL, + .user_data = viewgroup, + }); + + WM_manipulator_target_property_def_func( + mpr, "scale", + &(const struct wmManipulatorPropertyFnParams) { + .value_get_fn = manipulator_render_border_prop_size_get, + .value_set_fn = manipulator_render_border_prop_size_set, + .range_get_fn = NULL, + .user_data = viewgroup, + }); + } + +} + +void VIEW3D_WGT_camera_view(wmManipulatorGroupType *wgt) +{ + wgt->name = "Camera View Widgets"; + wgt->idname = "VIEW3D_WGT_camera_view"; + + wgt->flag = (WM_MANIPULATORGROUPTYPE_PERSISTENT | + WM_MANIPULATORGROUPTYPE_SCALE); + + wgt->poll = WIDGETGROUP_camera_view_poll; + wgt->setup = WIDGETGROUP_camera_view_setup; + wgt->draw_prepare = WIDGETGROUP_camera_view_draw_prepare; + wgt->refresh = WIDGETGROUP_camera_view_refresh; +} + +/** \} */ diff --git a/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c b/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c new file mode 100644 index 00000000000..e3bfd0ac300 --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c @@ -0,0 +1,118 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_view3d/view3d_manipulator_forcefield.c + * \ingroup spview3d + */ + + +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_object.h" + +#include "DNA_object_types.h" +#include "DNA_object_force.h" + +#include "ED_screen.h" +#include "ED_manipulator_library.h" + +#include "MEM_guardedalloc.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "view3d_intern.h" /* own include */ + +/* -------------------------------------------------------------------- */ + +/** \name Force Field Manipulators + * \{ */ + +static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) +{ + Object *ob = CTX_data_active_object(C); + + return (ob && ob->pd && ob->pd->forcefield); +} + +static void WIDGETGROUP_forcefield_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) +{ + const float col[4] = {0.8f, 0.8f, 0.45f, 0.5f}; + const float col_hi[4] = {0.8f, 0.8f, 0.45f, 1.0f}; + + /* only wind effector for now */ + wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__); + mgroup->customdata = wwrapper; + + wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_arrow_3d", mgroup, NULL); + wmManipulator *mpr = wwrapper->manipulator; + RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED); + ED_manipulator_arrow3d_set_ui_range(mpr, -200.0f, 200.0f); + ED_manipulator_arrow3d_set_range_fac(mpr, 6.0f); + WM_manipulator_set_color(mpr, col); + WM_manipulator_set_color_highlight(mpr, col_hi); +} + +static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmManipulatorGroup *mgroup) +{ + wmManipulatorWrapper *wwrapper = mgroup->customdata; + wmManipulator *mpr = wwrapper->manipulator; + Object *ob = CTX_data_active_object(C); + PartDeflect *pd = ob->pd; + + if (pd->forcefield == PFIELD_WIND) { + const float size = (ob->type == OB_EMPTY) ? ob->empty_drawsize : 1.0f; + const float ofs[3] = {0.0f, -size, 0.0f}; + PointerRNA field_ptr; + + RNA_pointer_create(&ob->id, &RNA_FieldSettings, pd, &field_ptr); + WM_manipulator_set_matrix_location(mpr, ob->obmat[3]); + WM_manipulator_set_matrix_rotation_from_z_axis(mpr, ob->obmat[2]); + WM_manipulator_set_matrix_offset_location(mpr, ofs); + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, false); + WM_manipulator_target_property_def_rna(mpr, "offset", &field_ptr, "strength", -1); + } + else { + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, true); + } +} + +void VIEW3D_WGT_force_field(wmManipulatorGroupType *wgt) +{ + wgt->name = "Force Field Widgets"; + wgt->idname = "VIEW3D_WGT_force_field"; + + wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT | + WM_MANIPULATORGROUPTYPE_3D | + WM_MANIPULATORGROUPTYPE_SCALE | + WM_MANIPULATORGROUPTYPE_DEPTH_3D); + + wgt->poll = WIDGETGROUP_forcefield_poll; + wgt->setup = WIDGETGROUP_forcefield_setup; + wgt->refresh = WIDGETGROUP_forcefield_refresh; +} + +/** \} */ + diff --git a/source/blender/editors/space_view3d/view3d_manipulator_lamp.c b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c new file mode 100644 index 00000000000..4b550fd0b2e --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c @@ -0,0 +1,297 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_view3d/view3d_manipulator_lamp.c + * \ingroup spview3d + */ + + +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_object.h" + +#include "DNA_object_types.h" +#include "DNA_lamp_types.h" + +#include "ED_screen.h" +#include "ED_manipulator_library.h" + +#include "MEM_guardedalloc.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "view3d_intern.h" /* own include */ + +/* -------------------------------------------------------------------- */ + +/** \name Spot Lamp Manipulators + * \{ */ + +static bool WIDGETGROUP_lamp_spot_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) +{ + Object *ob = CTX_data_active_object(C); + + if (ob && ob->type == OB_LAMP) { + Lamp *la = ob->data; + return (la->type == LA_SPOT); + } + return false; +} + +static void WIDGETGROUP_lamp_spot_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) +{ + const float color[4] = {0.5f, 0.5f, 1.0f, 1.0f}; + const float color_hi[4] = {0.8f, 0.8f, 0.45f, 1.0f}; + + wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__); + + wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_arrow_3d", mgroup, NULL); + wmManipulator *mpr = wwrapper->manipulator; + RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_INVERTED); + + mgroup->customdata = wwrapper; + + ED_manipulator_arrow3d_set_range_fac(mpr, 4.0f); + WM_manipulator_set_color(mpr, color); + WM_manipulator_set_color_highlight(mpr, color_hi); +} + +static void WIDGETGROUP_lamp_spot_refresh(const bContext *C, wmManipulatorGroup *mgroup) +{ + wmManipulatorWrapper *wwrapper = mgroup->customdata; + wmManipulator *mpr = wwrapper->manipulator; + Object *ob = CTX_data_active_object(C); + Lamp *la = ob->data; + float dir[3]; + + negate_v3_v3(dir, ob->obmat[2]); + + WM_manipulator_set_matrix_rotation_from_z_axis(mpr, dir); + WM_manipulator_set_matrix_location(mpr, ob->obmat[3]); + + /* need to set property here for undo. TODO would prefer to do this in _init */ + PointerRNA lamp_ptr; + const char *propname = "spot_size"; + RNA_pointer_create(&la->id, &RNA_Lamp, la, &lamp_ptr); + WM_manipulator_target_property_def_rna(mpr, "offset", &lamp_ptr, propname, -1); +} + +void VIEW3D_WGT_lamp_spot(wmManipulatorGroupType *wgt) +{ + wgt->name = "Spot Lamp Widgets"; + wgt->idname = "VIEW3D_WGT_lamp_spot"; + + wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT | + WM_MANIPULATORGROUPTYPE_3D | + WM_MANIPULATORGROUPTYPE_DEPTH_3D); + + wgt->poll = WIDGETGROUP_lamp_spot_poll; + wgt->setup = WIDGETGROUP_lamp_spot_setup; + wgt->refresh = WIDGETGROUP_lamp_spot_refresh; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ + +/** \name Area Lamp Manipulators + * \{ */ + +/* translate callbacks */ +static void manipulator_area_lamp_prop_size_get( + const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop, + void *value_p) +{ + float *value = value_p; + BLI_assert(mpr_prop->type->array_length == 2); + Lamp *la = mpr_prop->custom_func.user_data; + + value[0] = la->area_size; + value[1] = (la->area_shape == LA_AREA_RECT) ? la->area_sizey : la->area_size; +} + +static void manipulator_area_lamp_prop_size_set( + const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop, + const void *value_p) +{ + const float *value = value_p; + + BLI_assert(mpr_prop->type->array_length == 2); + Lamp *la = mpr_prop->custom_func.user_data; + if (la->area_shape == LA_AREA_RECT) { + la->area_size = value[0]; + la->area_sizey = value[1]; + } + else { + la->area_size = value[0]; + } +} + +static void manipulator_area_lamp_prop_size_range( + const wmManipulator *UNUSED(mpr), wmManipulatorProperty *UNUSED(mpr_prop), + void *value_p) +{ + float *value = value_p; + value[0] = 0.0f; + value[1] = FLT_MAX; +} + +static bool WIDGETGROUP_lamp_area_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) +{ + Object *ob = CTX_data_active_object(C); + + if (ob && ob->type == OB_LAMP) { + Lamp *la = ob->data; + return (la->type == LA_AREA); + } + return false; +} + +static void WIDGETGROUP_lamp_area_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) +{ + const float color[4] = {1.0f, 1.0f, 0.5f, 1.0f}; + const float color_hi[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + + wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__); + wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL); + wmManipulator *mpr = wwrapper->manipulator; + RNA_enum_set(mpr->ptr, "transform", + ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE); + + mgroup->customdata = wwrapper; + + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_HOVER, true); + WM_manipulator_set_color(mpr, color); + WM_manipulator_set_color_highlight(mpr, color_hi); +} + +static void WIDGETGROUP_lamp_area_refresh(const bContext *C, wmManipulatorGroup *mgroup) +{ + wmManipulatorWrapper *wwrapper = mgroup->customdata; + Object *ob = CTX_data_active_object(C); + Lamp *la = ob->data; + wmManipulator *mpr = wwrapper->manipulator; + + copy_m4_m4(mpr->matrix_basis, ob->obmat); + + RNA_enum_set(mpr->ptr, "transform", + ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE | + ((la->area_shape == LA_AREA_SQUARE) ? ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM : 0)); + + /* need to set property here for undo. TODO would prefer to do this in _init */ + WM_manipulator_target_property_def_func( + mpr, "scale", + &(const struct wmManipulatorPropertyFnParams) { + .value_get_fn = manipulator_area_lamp_prop_size_get, + .value_set_fn = manipulator_area_lamp_prop_size_set, + .range_get_fn = manipulator_area_lamp_prop_size_range, + .user_data = la, + }); +} + +void VIEW3D_WGT_lamp_area(wmManipulatorGroupType *wgt) +{ + wgt->name = "Area Lamp Widgets"; + wgt->idname = "VIEW3D_WGT_lamp_area"; + + wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT | + WM_MANIPULATORGROUPTYPE_3D | + WM_MANIPULATORGROUPTYPE_DEPTH_3D); + + wgt->poll = WIDGETGROUP_lamp_area_poll; + wgt->setup = WIDGETGROUP_lamp_area_setup; + wgt->refresh = WIDGETGROUP_lamp_area_refresh; +} + +/** \} */ + + +/* -------------------------------------------------------------------- */ + +/** \name Lamp Target Manipulator + * \{ */ + +static bool WIDGETGROUP_lamp_target_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) +{ + Object *ob = CTX_data_active_object(C); + + if (ob != NULL) { + if (ob->type == OB_LAMP) { + Lamp *la = ob->data; + return (ELEM(la->type, LA_SUN, LA_SPOT, LA_HEMI, LA_AREA)); + } + else if (ob->type == OB_CAMERA) { + return true; + } + } + return false; +} + +static void WIDGETGROUP_lamp_target_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) +{ + const float color[4] = {1.0f, 1.0f, 0.5f, 1.0f}; + const float color_hi[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + + wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__); + wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_grab_3d", mgroup, NULL); + wmManipulator *mpr = wwrapper->manipulator; + + mgroup->customdata = wwrapper; + + WM_manipulator_set_color(mpr, color); + WM_manipulator_set_color_highlight(mpr, color_hi); + + mpr->scale_basis = 0.05f; + + wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_transform_axis_target", true); + WM_manipulator_set_operator(mpr, ot, NULL); +} + +static void WIDGETGROUP_lamp_target_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup) +{ + wmManipulatorWrapper *wwrapper = mgroup->customdata; + Object *ob = CTX_data_active_object(C); + wmManipulator *mpr = wwrapper->manipulator; + + copy_m4_m4(mpr->matrix_basis, ob->obmat); + unit_m4(mpr->matrix_offset); + mpr->matrix_offset[3][2] = -2.4f / mpr->scale_basis; +} + +void VIEW3D_WGT_lamp_target(wmManipulatorGroupType *wgt) +{ + wgt->name = "Target Lamp Widgets"; + wgt->idname = "VIEW3D_WGT_lamp_target"; + + wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT | + WM_MANIPULATORGROUPTYPE_3D); + + wgt->poll = WIDGETGROUP_lamp_target_poll; + wgt->setup = WIDGETGROUP_lamp_target_setup; + wgt->draw_prepare = WIDGETGROUP_lamp_target_draw_prepare; +} + +/** \} */
\ No newline at end of file diff --git a/source/blender/editors/space_view3d/view3d_manipulators.c b/source/blender/editors/space_view3d/view3d_manipulators.c deleted file mode 100644 index 3a12fc31ba2..00000000000 --- a/source/blender/editors/space_view3d/view3d_manipulators.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_view3d/view3d_manipulators.c - * \ingroup spview3d - */ - - -#include "BLI_blenlib.h" -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#include "BKE_armature.h" -#include "BKE_camera.h" -#include "BKE_context.h" -#include "BKE_object.h" - -#include "DNA_armature_types.h" -#include "DNA_camera_types.h" -#include "DNA_lamp_types.h" -#include "DNA_object_types.h" -#include "DNA_object_force.h" - -#include "ED_armature.h" -#include "ED_screen.h" -#include "ED_manipulator_library.h" - -#include "MEM_guardedalloc.h" - -#include "RNA_access.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "view3d_intern.h" /* own include */ - -/* -------------------------------------------------------------------- */ - -/** \name Lamp Manipulators - * \{ */ - -static bool WIDGETGROUP_lamp_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) -{ - Object *ob = CTX_data_active_object(C); - - if (ob && ob->type == OB_LAMP) { - Lamp *la = ob->data; - return (la->type == LA_SPOT); - } - return false; -} - -static void WIDGETGROUP_lamp_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) -{ - const char *propname = "spot_size"; - - const float color[4] = {0.5f, 0.5f, 1.0f, 1.0f}; - const float color_hi[4] = {0.8f, 0.8f, 0.45f, 1.0f}; - - wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__); - - wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_arrow_3d", mgroup, propname, NULL); - RNA_enum_set(wwrapper->manipulator->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_INVERTED); - - mgroup->customdata = wwrapper; - - ED_manipulator_arrow3d_set_range_fac(wwrapper->manipulator, 4.0f); - WM_manipulator_set_color(wwrapper->manipulator, color); - WM_manipulator_set_color_highlight(wwrapper->manipulator, color_hi); -} - -static void WIDGETGROUP_lamp_refresh(const bContext *C, wmManipulatorGroup *mgroup) -{ - wmManipulatorWrapper *wwrapper = mgroup->customdata; - Object *ob = CTX_data_active_object(C); - Lamp *la = ob->data; - float dir[3]; - - negate_v3_v3(dir, ob->obmat[2]); - - WM_manipulator_set_matrix_rotation_from_z_axis(wwrapper->manipulator, dir); - WM_manipulator_set_matrix_location(wwrapper->manipulator, ob->obmat[3]); - - /* need to set property here for undo. TODO would prefer to do this in _init */ - PointerRNA lamp_ptr; - const char *propname = "spot_size"; - RNA_pointer_create(&la->id, &RNA_Lamp, la, &lamp_ptr); - WM_manipulator_target_property_def_rna(wwrapper->manipulator, "offset", &lamp_ptr, propname, -1); -} - -void VIEW3D_WGT_lamp(wmManipulatorGroupType *wgt) -{ - wgt->name = "Lamp Widgets"; - wgt->idname = "VIEW3D_WGT_lamp"; - - wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT | - WM_MANIPULATORGROUPTYPE_3D | - WM_MANIPULATORGROUPTYPE_DEPTH_3D); - - wgt->poll = WIDGETGROUP_lamp_poll; - wgt->setup = WIDGETGROUP_lamp_setup; - wgt->refresh = WIDGETGROUP_lamp_refresh; -} - -/** \} */ - - -/* -------------------------------------------------------------------- */ - -/** \name Camera Manipulators - * \{ */ - -struct CameraWidgetGroup { - wmManipulator *dop_dist; - wmManipulator *focal_len; - wmManipulator *ortho_scale; -}; - -static bool WIDGETGROUP_camera_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) -{ - Object *ob = CTX_data_active_object(C); - - return (ob && ob->type == OB_CAMERA); -} - -static void cameragroup_property_setup(wmManipulator *widget, Object *ob, Camera *ca, const bool is_ortho) -{ - const float scale[3] = {1.0f / len_v3(ob->obmat[0]), 1.0f / len_v3(ob->obmat[1]), 1.0f / len_v3(ob->obmat[2])}; - const float scale_fac = ca->drawsize; - const float drawsize = is_ortho ? - (0.5f * ca->ortho_scale) : - (scale_fac / ((scale[0] + scale[1] + scale[2]) / 3.0f)); - const float half_sensor = 0.5f * ((ca->sensor_fit == CAMERA_SENSOR_FIT_VERT) ? ca->sensor_y : ca->sensor_x); - const char *propname = is_ortho ? "ortho_scale" : "lens"; - - PointerRNA camera_ptr; - float min, max, range; - float step, precision; - - RNA_pointer_create(&ca->id, &RNA_Camera, ca, &camera_ptr); - - /* get property range */ - PropertyRNA *prop = RNA_struct_find_property(&camera_ptr, propname); - RNA_property_float_ui_range(&camera_ptr, prop, &min, &max, &step, &precision); - range = max - min; - - ED_manipulator_arrow3d_set_range_fac(widget, is_ortho ? (scale_fac * range) : (drawsize * range / half_sensor)); -} - -static void WIDGETGROUP_camera_setup(const bContext *C, wmManipulatorGroup *mgroup) -{ - Object *ob = CTX_data_active_object(C); - Camera *ca = ob->data; - float dir[3]; - - const wmManipulatorType *wt_arrow = WM_manipulatortype_find("MANIPULATOR_WT_arrow_3d", true); - - struct CameraWidgetGroup *camgroup = MEM_callocN(sizeof(struct CameraWidgetGroup), __func__); - mgroup->customdata = camgroup; - - negate_v3_v3(dir, ob->obmat[2]); - - /* dof distance */ - { - const float color[4] = {1.0f, 0.3f, 0.0f, 1.0f}; - const float color_hi[4] = {1.0f, 0.3f, 0.0f, 1.0f}; - - camgroup->dop_dist = WM_manipulator_new_ptr(wt_arrow, mgroup, "dof_distance", NULL); - RNA_enum_set(camgroup->dop_dist->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CROSS); - WM_manipulator_set_flag(camgroup->dop_dist, WM_MANIPULATOR_DRAW_HOVER, true); - WM_manipulator_set_color(camgroup->dop_dist, color); - WM_manipulator_set_color_highlight(camgroup->dop_dist, color_hi); - } - - /* focal length - * - logic/calculations are similar to BKE_camera_view_frame_ex, better keep in sync */ - { - const float color[4] = {1.0f, 1.0, 0.27f, 0.5f}; - const float color_hi[4] = {1.0f, 1.0, 0.27f, 1.0f}; - - camgroup->focal_len = WM_manipulator_new_ptr(wt_arrow, mgroup, "focal_len", NULL); - RNA_enum_set(camgroup->focal_len->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE); - RNA_enum_set(camgroup->focal_len->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED); - - WM_manipulator_set_color(camgroup->focal_len, color); - WM_manipulator_set_color_highlight(camgroup->focal_len, color_hi); - cameragroup_property_setup(camgroup->focal_len, ob, ca, false); - - camgroup->ortho_scale = WM_manipulator_new_ptr(wt_arrow, mgroup, "ortho_scale", NULL); - RNA_enum_set(camgroup->ortho_scale->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE); - RNA_enum_set(camgroup->ortho_scale->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED); - - WM_manipulator_set_color(camgroup->ortho_scale, color); - WM_manipulator_set_color_highlight(camgroup->ortho_scale, color_hi); - cameragroup_property_setup(camgroup->ortho_scale, ob, ca, true); - } -} - -static void WIDGETGROUP_camera_refresh(const bContext *C, wmManipulatorGroup *mgroup) -{ - if (!mgroup->customdata) - return; - - struct CameraWidgetGroup *camgroup = mgroup->customdata; - Object *ob = CTX_data_active_object(C); - Camera *ca = ob->data; - PointerRNA camera_ptr; - float dir[3]; - - RNA_pointer_create(&ca->id, &RNA_Camera, ca, &camera_ptr); - - negate_v3_v3(dir, ob->obmat[2]); - - if (ca->flag & CAM_SHOWLIMITS) { - WM_manipulator_set_matrix_location(camgroup->dop_dist, ob->obmat[3]); - WM_manipulator_set_matrix_rotation_from_yz_axis(camgroup->dop_dist, ob->obmat[1], dir); - WM_manipulator_set_scale(camgroup->dop_dist, ca->drawsize); - WM_manipulator_set_flag(camgroup->dop_dist, WM_MANIPULATOR_HIDDEN, false); - - /* need to set property here for undo. TODO would prefer to do this in _init */ - WM_manipulator_target_property_def_rna(camgroup->dop_dist, "offset", &camera_ptr, "dof_distance", -1); - } - else { - WM_manipulator_set_flag(camgroup->dop_dist, WM_MANIPULATOR_HIDDEN, true); - } - - /* TODO - make focal length/ortho scale widget optional */ - if (true) { - const bool is_ortho = (ca->type == CAM_ORTHO); - const float scale[3] = {1.0f / len_v3(ob->obmat[0]), 1.0f / len_v3(ob->obmat[1]), 1.0f / len_v3(ob->obmat[2])}; - const float scale_fac = ca->drawsize; - const float drawsize = is_ortho ? - (0.5f * ca->ortho_scale) : - (scale_fac / ((scale[0] + scale[1] + scale[2]) / 3.0f)); - float offset[3]; - float aspect[2]; - - wmManipulator *widget = is_ortho ? camgroup->ortho_scale : camgroup->focal_len; - WM_manipulator_set_flag(widget, WM_MANIPULATOR_HIDDEN, false); - WM_manipulator_set_flag(is_ortho ? camgroup->focal_len : camgroup->ortho_scale, WM_MANIPULATOR_HIDDEN, true); - - - /* account for lens shifting */ - offset[0] = ((ob->size[0] > 0.0f) ? -2.0f : 2.0f) * ca->shiftx; - offset[1] = 2.0f * ca->shifty; - offset[2] = 0.0f; - - /* get aspect */ - const Scene *scene = CTX_data_scene(C); - const float aspx = (float)scene->r.xsch * scene->r.xasp; - const float aspy = (float)scene->r.ysch * scene->r.yasp; - const int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, aspx, aspy); - aspect[0] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? 1.0 : aspx / aspy; - aspect[1] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? aspy / aspx : 1.0f; - - WM_manipulator_set_matrix_location(widget, ob->obmat[3]); - WM_manipulator_set_matrix_rotation_from_yz_axis(widget, ob->obmat[1], dir); - - RNA_float_set_array(widget->ptr, "aspect", aspect); - - WM_manipulator_set_matrix_offset_location(widget, offset); - WM_manipulator_set_scale(widget, drawsize); - - /* need to set property here for undo. TODO would prefer to do this in _init */ - WM_manipulator_target_property_def_rna(camgroup->focal_len, "offset", &camera_ptr, "lens", -1); - WM_manipulator_target_property_def_rna(camgroup->ortho_scale, "offset", &camera_ptr, "ortho_scale", -1); - } -} - -void VIEW3D_WGT_camera(wmManipulatorGroupType *wgt) -{ - wgt->name = "Camera Widgets"; - wgt->idname = "VIEW3D_WGT_camera"; - - wgt->flag = (WM_MANIPULATORGROUPTYPE_PERSISTENT | - WM_MANIPULATORGROUPTYPE_3D | - WM_MANIPULATORGROUPTYPE_SCALE | - WM_MANIPULATORGROUPTYPE_DEPTH_3D); - - wgt->poll = WIDGETGROUP_camera_poll; - wgt->setup = WIDGETGROUP_camera_setup; - wgt->refresh = WIDGETGROUP_camera_refresh; -} - -/** \} */ - - -/* -------------------------------------------------------------------- */ - -/** \name Force Field Manipulators - * \{ */ - -static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) -{ - Object *ob = CTX_data_active_object(C); - - return (ob && ob->pd && ob->pd->forcefield); -} - -static void WIDGETGROUP_forcefield_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) -{ - const float col[4] = {0.8f, 0.8f, 0.45f, 0.5f}; - const float col_hi[4] = {0.8f, 0.8f, 0.45f, 1.0f}; - - /* only wind effector for now */ - wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__); - mgroup->customdata = wwrapper; - - wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_arrow_3d", mgroup, "field_strength", NULL); - RNA_enum_set(wwrapper->manipulator->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED); - ED_manipulator_arrow3d_set_ui_range(wwrapper->manipulator, -200.0f, 200.0f); - ED_manipulator_arrow3d_set_range_fac(wwrapper->manipulator, 6.0f); - WM_manipulator_set_color(wwrapper->manipulator, col); - WM_manipulator_set_color_highlight(wwrapper->manipulator, col_hi); -} - -static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmManipulatorGroup *mgroup) -{ - wmManipulatorWrapper *wwrapper = mgroup->customdata; - Object *ob = CTX_data_active_object(C); - PartDeflect *pd = ob->pd; - - if (pd->forcefield == PFIELD_WIND) { - const float size = (ob->type == OB_EMPTY) ? ob->empty_drawsize : 1.0f; - const float ofs[3] = {0.0f, -size, 0.0f}; - PointerRNA field_ptr; - - RNA_pointer_create(&ob->id, &RNA_FieldSettings, pd, &field_ptr); - WM_manipulator_set_matrix_location(wwrapper->manipulator, ob->obmat[3]); - WM_manipulator_set_matrix_rotation_from_z_axis(wwrapper->manipulator, ob->obmat[2]); - WM_manipulator_set_matrix_offset_location(wwrapper->manipulator, ofs); - WM_manipulator_set_flag(wwrapper->manipulator, WM_MANIPULATOR_HIDDEN, false); - WM_manipulator_target_property_def_rna(wwrapper->manipulator, "offset", &field_ptr, "strength", -1); - } - else { - WM_manipulator_set_flag(wwrapper->manipulator, WM_MANIPULATOR_HIDDEN, true); - } -} - -void VIEW3D_WGT_force_field(wmManipulatorGroupType *wgt) -{ - wgt->name = "Force Field Widgets"; - wgt->idname = "VIEW3D_WGT_force_field"; - - wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT | - WM_MANIPULATORGROUPTYPE_3D | - WM_MANIPULATORGROUPTYPE_SCALE | - WM_MANIPULATORGROUPTYPE_DEPTH_3D); - - wgt->poll = WIDGETGROUP_forcefield_poll; - wgt->setup = WIDGETGROUP_forcefield_setup; - wgt->refresh = WIDGETGROUP_forcefield_refresh; -} - -/** \} */ - diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index f62a12b071f..acf8ed29c6b 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -738,7 +738,7 @@ static void view3d_ruler_item_project(RulerInfo *ruler_info, float r_co[3], /* use for mousemove events */ static bool view3d_ruler_item_mousemove( - RulerInfo *ruler_info, const int mval[2], + const bContext *C, RulerInfo *ruler_info, const int mval[2], const bool do_thickness, const bool do_snap) { const float eps_bias = 0.0002f; @@ -763,7 +763,7 @@ static bool view3d_ruler_item_mousemove( co_other = ruler_item->co[ruler_item->co_index == 0 ? 2 : 0]; if (ED_transform_snap_object_project_view3d_mixed( - ruler_info->snap_context, + C, ruler_info->snap_context, SCE_SELECT_FACE, &(const struct SnapObjectParams){ .snap_select = SNAP_ALL, @@ -776,7 +776,7 @@ static bool view3d_ruler_item_mousemove( /* add some bias */ madd_v3_v3v3fl(ray_start, co, ray_normal, eps_bias); ED_transform_snap_object_project_ray( - ruler_info->snap_context, + C, ruler_info->snap_context, &(const struct SnapObjectParams){ .snap_select = SNAP_ALL, .use_object_edit_cage = true, @@ -792,7 +792,7 @@ static bool view3d_ruler_item_mousemove( bool use_depth = (v3d->drawtype >= OB_SOLID); if (ED_transform_snap_object_project_view3d_mixed( - ruler_info->snap_context, + C, ruler_info->snap_context, (SCE_SELECT_VERTEX | SCE_SELECT_EDGE) | (use_depth ? SCE_SELECT_FACE : 0), &(const struct SnapObjectParams){ .snap_select = SNAP_ALL, @@ -924,7 +924,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) if (use_depth) { /* snap the first point added, not essential but handy */ ruler_item->co_index = 0; - view3d_ruler_item_mousemove(ruler_info, event->mval, false, true); + view3d_ruler_item_mousemove(C, ruler_info, event->mval, false, true); copy_v3_v3(ruler_info->drag_start_co, ruler_item->co[ruler_item->co_index]); } else { @@ -977,7 +977,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) } /* update the new location */ - view3d_ruler_item_mousemove(ruler_info, event->mval, + view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->shift != 0, event->ctrl != 0); do_draw = true; } @@ -1026,7 +1026,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) case MOUSEMOVE: { if (ruler_info->state == RULER_STATE_DRAG) { - if (view3d_ruler_item_mousemove(ruler_info, event->mval, + if (view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->shift != 0, event->ctrl != 0)) { do_draw = true; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 8812db7bdec..2534fdfd6f0 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -458,7 +458,7 @@ static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, cons } } -static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) +static void do_lasso_select_mesh(const bContext *C, ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) { LassoSelectUserData data; ToolSettings *ts = vc->scene->toolsettings; @@ -479,24 +479,24 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); gpuLoadMatrix(vc->rv3d->viewmat); - bbsel = EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + bbsel = EDBM_backbuf_border_mask_init(C, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); if (ts->selectmode & SCE_SELECT_VERTEX) { if (bbsel) { edbm_backbuf_check_and_select_verts(vc->em, select); } else { - mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenVert(C, vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } if (ts->selectmode & SCE_SELECT_EDGE) { /* Does both bbsel and non-bbsel versions (need screen cos for both) */ data.pass = 0; - mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); + mesh_foreachScreenEdge(C, vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); if (data.is_done == false) { data.pass = 1; - mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); + mesh_foreachScreenEdge(C, vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); } } @@ -505,7 +505,7 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m edbm_backbuf_check_and_select_faces(vc->em, select); } else { - mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenFace(C, vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -704,7 +704,7 @@ static void do_lasso_select_meshobject__doSelectVert(void *userData, MVert *mv, BKE_BIT_TEST_SET(mv->flag, data->select, SELECT); } } -static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) +static void do_lasso_select_paintvert(const bContext *C, ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) { const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0; Object *ob = vc->obact; @@ -722,7 +722,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh if (use_zbuf) { bm_vertoffs = me->totvert + 1; /* max index array */ - EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + EDBM_backbuf_border_mask_init(C, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); edbm_backbuf_check_and_select_verts_obmode(me, select); @@ -735,7 +735,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); - meshobject_foreachScreenVert(vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + meshobject_foreachScreenVert(C, vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } @@ -744,7 +744,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh } paintvert_flush_flags(ob); } -static void do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) +static void do_lasso_select_paintface(const bContext *C, ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) { Object *ob = vc->obact; Mesh *me = ob->data; @@ -759,7 +759,7 @@ static void do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], sh bm_vertoffs = me->totpoly + 1; /* max index array */ BLI_lasso_boundbox(&rect, mcords, moves); - EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + EDBM_backbuf_border_mask_init(C, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); edbm_backbuf_check_and_select_tfaces(me, select); @@ -807,9 +807,9 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, if (vc->obedit == NULL) { /* Object Mode */ if (BKE_paint_select_face_test(ob)) - do_lasso_select_paintface(vc, mcords, moves, extend, select); + do_lasso_select_paintface(C, vc, mcords, moves, extend, select); else if (BKE_paint_select_vert_test(ob)) - do_lasso_select_paintvert(vc, mcords, moves, extend, select); + do_lasso_select_paintvert(C, vc, mcords, moves, extend, select); else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) { /* pass */ } @@ -825,7 +825,7 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, else { /* Edit Mode */ switch (vc->obedit->type) { case OB_MESH: - do_lasso_select_mesh(vc, mcords, moves, extend, select); + do_lasso_select_mesh(C, vc, mcords, moves, extend, select); break; case OB_CURVE: case OB_SURF: @@ -1180,7 +1180,7 @@ static int selectbuffer_ret_hits_5(unsigned int *buffer, const int hits15, const /* we want a select buffer with bones, if there are... */ /* so check three selection levels and compare */ static int mixed_bones_object_selectbuffer( - ViewContext *vc, unsigned int *buffer, const int mval[2], + const bContext *C, ViewContext *vc, unsigned int *buffer, const int mval[2], bool use_cycle, bool enumerate, bool *r_do_nearest) { @@ -1220,7 +1220,7 @@ static int mixed_bones_object_selectbuffer( view3d_opengl_select_cache_begin(); BLI_rcti_init_pt_radius(&rect, mval, 14); - hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode); + hits15 = view3d_opengl_select(C, vc, buffer, MAXPICKBUF, &rect, select_mode); if (hits15 == 1) { hits = selectbuffer_ret_hits_15(buffer, hits15); goto finally; @@ -1231,7 +1231,7 @@ static int mixed_bones_object_selectbuffer( offs = 4 * hits15; BLI_rcti_init_pt_radius(&rect, mval, 9); - hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode); + hits9 = view3d_opengl_select(C, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode); if (hits9 == 1) { hits = selectbuffer_ret_hits_9(buffer, hits15, hits9); goto finally; @@ -1241,7 +1241,7 @@ static int mixed_bones_object_selectbuffer( offs += 4 * hits9; BLI_rcti_init_pt_radius(&rect, mval, 5); - hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode); + hits5 = view3d_opengl_select(C, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode); if (hits5 == 1) { hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); goto finally; @@ -1363,7 +1363,7 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2]) view3d_operator_needs_opengl(C); view3d_set_viewcontext(C, &vc); - hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, false, false, &do_nearest); + hits = mixed_bones_object_selectbuffer(C, &vc, buffer, mval, false, false, &do_nearest); if (hits > 0) { const bool has_bones = selectbuffer_has_bones(buffer, hits); @@ -1460,7 +1460,7 @@ static bool ed_object_select_pick( // TIMEIT_START(select_time); /* if objects have posemode set, the bones are in the same selection buffer */ - hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, true, enumerate, &do_nearest); + hits = mixed_bones_object_selectbuffer(C, &vc, buffer, mval, true, enumerate, &do_nearest); // TIMEIT_END(select_time); @@ -1653,7 +1653,7 @@ static void do_paintvert_box_select__doSelectVert(void *userData, MVert *mv, con BKE_BIT_TEST_SET(mv->flag, data->select, SELECT); } } -static int do_paintvert_box_select(ViewContext *vc, rcti *rect, bool select, bool extend) +static int do_paintvert_box_select(const bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend) { const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0; Mesh *me; @@ -1677,7 +1677,7 @@ static int do_paintvert_box_select(ViewContext *vc, rcti *rect, bool select, boo if (use_zbuf) { selar = MEM_callocN(me->totvert + 1, "selar"); - ED_view3d_backbuf_validate(vc); + ED_view3d_backbuf_validate(C, vc); ibuf = IMB_allocImBuf(size[0], size[1], 32, IB_rect); rt = ibuf->rect; @@ -1725,7 +1725,7 @@ static int do_paintvert_box_select(ViewContext *vc, rcti *rect, bool select, boo ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); - meshobject_foreachScreenVert(vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + meshobject_foreachScreenVert(C, vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } if (select == false) { @@ -1840,7 +1840,7 @@ static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, const BM_face_select_set(data->vc->em->bm, efa, data->select); } } -static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool extend) +static int do_mesh_box_select(const bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend) { BoxSelectUserData data; ToolSettings *ts = vc->scene->toolsettings; @@ -1855,25 +1855,25 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool ext ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); gpuLoadMatrix(vc->rv3d->viewmat); - bbsel = EDBM_backbuf_border_init(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax); + bbsel = EDBM_backbuf_border_init(C, vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax); if (ts->selectmode & SCE_SELECT_VERTEX) { if (bbsel) { edbm_backbuf_check_and_select_verts(vc->em, select); } else { - mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenVert(C, vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } if (ts->selectmode & SCE_SELECT_EDGE) { /* Does both bbsel and non-bbsel versions (need screen cos for both) */ data.pass = 0; - mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); + mesh_foreachScreenEdge(C, vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); if (data.is_done == 0) { data.pass = 1; - mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); + mesh_foreachScreenEdge(C, vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); } } @@ -1882,7 +1882,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool ext edbm_backbuf_check_and_select_faces(vc->em, select); } else { - mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenFace(C, vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -1893,7 +1893,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, bool select, bool ext return OPERATOR_FINISHED; } -static int do_meta_box_select(ViewContext *vc, rcti *rect, bool select, bool extend) +static int do_meta_box_select(const bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend) { MetaBall *mb = (MetaBall *)vc->obedit->data; MetaElem *ml; @@ -1902,7 +1902,7 @@ static int do_meta_box_select(ViewContext *vc, rcti *rect, bool select, bool ext unsigned int buffer[MAXPICKBUF]; int hits; - hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL); + hits = view3d_opengl_select(C, vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL); if (extend == false && select) BKE_mball_deselect_all(mb); @@ -1927,7 +1927,7 @@ static int do_meta_box_select(ViewContext *vc, rcti *rect, bool select, bool ext return OPERATOR_FINISHED; } -static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool extend) +static int do_armature_box_select(const bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend) { bArmature *arm = vc->obedit->data; EditBone *ebone; @@ -1936,7 +1936,7 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool unsigned int buffer[MAXPICKBUF]; int hits; - hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL); + hits = view3d_opengl_select(C, vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL); /* clear flag we use to detect point was affected */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) @@ -2054,7 +2054,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b /* selection buffer now has bones potentially too, so we add MAXPICKBUF */ vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(unsigned int), "selection buffer"); - hits = view3d_opengl_select(vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL); + hits = view3d_opengl_select(C, vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL); /* * LOGIC NOTES (theeth): * The buffer and ListBase have the same relative order, which makes the selection @@ -2148,7 +2148,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) switch (vc.obedit->type) { case OB_MESH: vc.em = BKE_editmesh_from_object(vc.obedit); - ret = do_mesh_box_select(&vc, &rect, select, extend); + ret = do_mesh_box_select(C, &vc, &rect, select, extend); // if (EM_texFaceCheck()) if (ret & OPERATOR_FINISHED) { WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); @@ -2162,13 +2162,13 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) } break; case OB_MBALL: - ret = do_meta_box_select(&vc, &rect, select, extend); + ret = do_meta_box_select(C, &vc, &rect, select, extend); if (ret & OPERATOR_FINISHED) { WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); } break; case OB_ARMATURE: - ret = do_armature_box_select(&vc, &rect, select, extend); + ret = do_armature_box_select(C, &vc, &rect, select, extend); if (ret & OPERATOR_FINISHED) { WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, vc.obedit); } @@ -2189,10 +2189,10 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) ret = ED_sculpt_mask_box_select(C, &vc, &rect, select, extend); } else if (vc.obact && BKE_paint_select_face_test(vc.obact)) { - ret = do_paintface_box_select(&vc, &rect, select, extend); + ret = do_paintface_box_select(C, &vc, &rect, select, extend); } else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) { - ret = do_paintvert_box_select(&vc, &rect, select, extend); + ret = do_paintvert_box_select(C, &vc, &rect, select, extend); } else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) { ret = PE_border_select(C, &rect, select, extend); @@ -2441,13 +2441,13 @@ static void mesh_circle_doSelectFace(void *userData, BMFace *efa, const float sc } } -static void mesh_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) +static void mesh_circle_select(const bContext *C, ViewContext *vc, const bool select, const int mval[2], float rad) { ToolSettings *ts = vc->scene->toolsettings; int bbsel; CircleSelectUserData data; - bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f)); + bbsel = EDBM_backbuf_circle_init(C, vc, mval[0], mval[1], (short)(rad + 1.0f)); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ vc->em = BKE_editmesh_from_object(vc->obedit); @@ -2459,7 +2459,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva edbm_backbuf_check_and_select_verts(vc->em, select); } else { - mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenVert(C, vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -2468,7 +2468,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva edbm_backbuf_check_and_select_edges(vc->em, select); } else { - mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); + mesh_foreachScreenEdge(C, vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); } } @@ -2477,7 +2477,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva edbm_backbuf_check_and_select_faces(vc->em, select); } else { - mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + mesh_foreachScreenFace(C, vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -2485,7 +2485,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva EDBM_selectmode_flush(vc->em); } -static void paint_facesel_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) +static void paint_facesel_circle_select(const bContext *C, ViewContext *vc, const bool select, const int mval[2], float rad) { Object *ob = vc->obact; Mesh *me = ob->data; @@ -2493,7 +2493,7 @@ static void paint_facesel_circle_select(ViewContext *vc, const bool select, cons bm_vertoffs = me->totpoly + 1; /* max index array */ - bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f)); + bbsel = EDBM_backbuf_circle_init(C, vc, mval[0], mval[1], (short)(rad + 1.0f)); if (bbsel) { edbm_backbuf_check_and_select_tfaces(me, select); EDBM_backbuf_free(); @@ -2509,7 +2509,7 @@ static void paint_vertsel_circle_select_doSelectVert(void *userData, MVert *mv, BKE_BIT_TEST_SET(mv->flag, data->select, SELECT); } } -static void paint_vertsel_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) +static void paint_vertsel_circle_select(const bContext *C, ViewContext *vc, const bool select, const int mval[2], float rad) { const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0; Object *ob = vc->obact; @@ -2520,7 +2520,7 @@ static void paint_vertsel_circle_select(ViewContext *vc, const bool select, cons if (use_zbuf) { bm_vertoffs = me->totvert + 1; /* max index array */ - bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f)); + bbsel = EDBM_backbuf_circle_init(C, vc, mval[0], mval[1], (short)(rad + 1.0f)); if (bbsel) { edbm_backbuf_check_and_select_verts_obmode(me, select); EDBM_backbuf_free(); @@ -2532,7 +2532,7 @@ static void paint_vertsel_circle_select(ViewContext *vc, const bool select, cons ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */ view3d_userdata_circleselect_init(&data, vc, select, mval, rad); - meshobject_foreachScreenVert(vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + meshobject_foreachScreenVert(C, vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } if (select != LEFTMOUSE) { @@ -2786,11 +2786,11 @@ static void mball_circle_select(ViewContext *vc, const bool select, const int mv /** Callbacks for circle selection in Editmode */ -static void obedit_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) +static void obedit_circle_select(const bContext *C, ViewContext *vc, const bool select, const int mval[2], float rad) { switch (vc->obedit->type) { case OB_MESH: - mesh_circle_select(vc, select, mval, rad); + mesh_circle_select(C, vc, select, mval, rad); break; case OB_CURVE: case OB_SURF: @@ -2858,15 +2858,15 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) view3d_set_viewcontext(C, &vc); if (CTX_data_edit_object(C)) { - obedit_circle_select(&vc, select, mval, (float)radius); + obedit_circle_select(C, &vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); } else if (BKE_paint_select_face_test(obact)) { - paint_facesel_circle_select(&vc, select, mval, (float)radius); + paint_facesel_circle_select(C, &vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); } else if (BKE_paint_select_vert_test(obact)) { - paint_vertsel_circle_select(&vc, select, mval, (float)radius); + paint_vertsel_circle_select(C, &vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); } else if (obact->mode & OB_MODE_POSE) { diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 8e566b8da1a..1df29201bf6 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -74,9 +74,12 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) RegionView3D *rv3d = CTX_wm_region_data(C); TransVertStore tvs = {NULL}; TransVert *tv; + EvaluationContext eval_ctx; float gridf, imat[3][3], bmat[3][3], vec[3]; int a; + CTX_data_eval_ctx(C, &eval_ctx); + gridf = rv3d->gridview; if (obedit) { @@ -163,7 +166,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) if (ob->parent) { float originmat[3][3]; - BKE_object_where_is_calc_ex(scene, NULL, ob, originmat); + BKE_object_where_is_calc_ex(&eval_ctx, scene, NULL, ob, originmat); invert_m3_m3(imat, originmat); mul_m3_v3(imat, vec); @@ -214,11 +217,14 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global View3D *v3d = CTX_wm_view3d(C); TransVertStore tvs = {NULL}; TransVert *tv; + EvaluationContext eval_ctx; float imat[3][3], bmat[3][3]; float center_global[3]; float offset_global[3]; int a; + CTX_data_eval_ctx(C, &eval_ctx); + if (use_offset) { if ((v3d && v3d->around == V3D_AROUND_ACTIVE) && snap_calc_active_center(C, true, center_global)) @@ -371,7 +377,7 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global if (ob->parent) { float originmat[3][3]; - BKE_object_where_is_calc_ex(scene, NULL, ob, originmat); + BKE_object_where_is_calc_ex(&eval_ctx, scene, NULL, ob, originmat); invert_m3_m3(imat, originmat); mul_m3_v3(imat, cursor_parent); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 854f71b17b3..3ffd21294df 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -442,6 +442,9 @@ void ED_view3d_smooth_view_force_finish( View3D *v3d, ARegion *ar) { RegionView3D *rv3d = ar->regiondata; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); if (rv3d && rv3d->sms) { rv3d->sms->time_allowed = 0.0; /* force finishing */ @@ -450,7 +453,7 @@ void ED_view3d_smooth_view_force_finish( /* force update of view matrix so tools that run immediately after * can use them without redrawing first */ Scene *scene = CTX_data_scene(C); - ED_view3d_update_viewmat(scene, v3d, ar, NULL, NULL, NULL); + ED_view3d_update_viewmat(&eval_ctx, scene, v3d, ar, NULL, NULL, NULL); } } @@ -809,19 +812,100 @@ bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const BoundBox *bb) return view3d_boundbox_clip_m4(bb, rv3d->persmatob); } -float ED_view3d_depth_read_cached(const ViewContext *vc, int x, int y) +/* -------------------------------------------------------------------- */ + +/** \name Depth Utilities + * \{ */ + +float ED_view3d_depth_read_cached(const ViewContext *vc, const int mval[2]) { ViewDepths *vd = vc->rv3d->depths; - x -= vc->ar->winrct.xmin; - y -= vc->ar->winrct.ymin; + int x = mval[0]; + int y = mval[1]; - if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h) + if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h) { return vd->depths[y * vd->w + x]; - else - return 1; + } + else { + BLI_assert(1.0 <= vd->depth_range[1]); + return 1.0f; + } +} + +bool ED_view3d_depth_read_cached_normal( + const ViewContext *vc, const int mval[2], + float r_normal[3]) +{ + /* Note: we could support passing in a radius. + * For now just read 9 pixels. */ + + /* pixels surrounding */ + bool depths_valid[9] = {false}; + float coords[9][3] = {{0}}; + + ARegion *ar = vc->ar; + const ViewDepths *depths = vc->rv3d->depths; + + for (int x = 0, i = 0; x < 2; x++) { + for (int y = 0; y < 2; y++) { + const int mval_ofs[2] = {mval[0] + (x - 1), mval[1] + (y - 1)}; + + const double depth = (double)ED_view3d_depth_read_cached(vc, mval_ofs); + if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) { + if (ED_view3d_depth_unproject(ar, mval_ofs, depth, coords[i])) { + depths_valid[i] = true; + } + } + i++; + } + } + + const int edges[2][6][2] = { + /* x edges */ + {{0, 1}, {1, 2}, + {3, 4}, {4, 5}, + {6, 7}, {7, 8}}, + /* y edges */ + {{0, 3}, {3, 6}, + {1, 4}, {4, 7}, + {2, 5}, {5, 8}}, + }; + + float cross[2][3] = {{0.0f}}; + + for (int i = 0; i < 6; i++) { + for (int axis = 0; axis < 2; axis++) { + if (depths_valid[edges[axis][i][0]] && depths_valid[edges[axis][i][1]]) { + float delta[3]; + sub_v3_v3v3(delta, coords[edges[axis][i][0]], coords[edges[axis][i][1]]); + add_v3_v3(cross[axis], delta); + } + } + } + + cross_v3_v3v3(r_normal, cross[0], cross[1]); + + if (normalize_v3(r_normal) != 0.0f) { + return true; + } + else { + return false; + } } +bool ED_view3d_depth_unproject( + const ARegion *ar, + const int mval[2], const double depth, + float r_location_world[3]) +{ + float centx = (float)mval[0] + 0.5f; + float centy = (float)mval[1] + 0.5f; + return ED_view3d_unproject(ar, centx, centy, depth, r_location_world); +} + +/** \} */ + void ED_view3d_depth_tag_update(RegionView3D *rv3d) { if (rv3d->depths) @@ -1022,11 +1106,11 @@ bool ED_view3d_lock(RegionView3D *rv3d) } /* don't set windows active in here, is used by renderwin too */ -void view3d_viewmatrix_set(Scene *scene, const View3D *v3d, RegionView3D *rv3d) +void view3d_viewmatrix_set(EvaluationContext *eval_ctx, Scene *scene, const View3D *v3d, RegionView3D *rv3d) { if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */ if (v3d->camera) { - BKE_object_where_is_calc(scene, v3d->camera); + BKE_object_where_is_calc(eval_ctx, scene, v3d->camera); obmat_to_viewmat(rv3d, v3d->camera); } else { @@ -1111,7 +1195,7 @@ void view3d_opengl_select_cache_end(void) * \note (vc->obedit == NULL) can be set to explicitly skip edit-object selection. */ int view3d_opengl_select( - ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input, + const bContext *C, ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input, eV3DSelectMode select_mode) { Depsgraph *graph = vc->depsgraph; @@ -1172,7 +1256,7 @@ int view3d_opengl_select( /* Important we use the 'viewmat' and don't re-calculate since * the object & bone view locking takes 'rect' into account, see: T51629. */ - ED_view3d_draw_setup_view(vc->win, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect); + ED_view3d_draw_setup_view(vc->win, C, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect); if (v3d->drawtype > OB_WIRE) { v3d->zbuf = true; @@ -1216,7 +1300,7 @@ int view3d_opengl_select( } G.f &= ~G_PICKSEL; - ED_view3d_draw_setup_view(vc->win, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL); + ED_view3d_draw_setup_view(vc->win, C, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL); if (v3d->drawtype > OB_WIRE) { v3d->zbuf = 0; diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 71a4980d4a6..4ff084129c3 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -423,7 +423,7 @@ static void walk_navigation_mode_set(bContext *C, wmOperator *op, WalkInfo *walk * \param r_distance Distance to the hit point */ static bool walk_floor_distance_get( - RegionView3D *rv3d, WalkInfo *walk, const float dvec[3], + const bContext *C, RegionView3D *rv3d, WalkInfo *walk, const float dvec[3], float *r_distance) { float ray_normal[3] = {0, 0, -1}; /* down */ @@ -441,7 +441,7 @@ static bool walk_floor_distance_get( add_v3_v3(ray_start, dvec_tmp); ret = ED_transform_snap_object_project_ray( - walk->snap_context, + C, walk->snap_context, &(const struct SnapObjectParams){ .snap_select = SNAP_ALL, }, @@ -459,7 +459,7 @@ static bool walk_floor_distance_get( * \param r_normal Normal of the hit surface, transformed to always face the camera */ static bool walk_ray_cast( - RegionView3D *rv3d, WalkInfo *walk, + const bContext *C, RegionView3D *rv3d, WalkInfo *walk, float r_location[3], float r_normal[3], float *ray_distance) { float ray_normal[3] = {0, 0, -1}; /* forward */ @@ -475,7 +475,7 @@ static bool walk_ray_cast( normalize_v3(ray_normal); ret = ED_transform_snap_object_project_ray( - walk->snap_context, + C, walk->snap_context, &(const struct SnapObjectParams){ .snap_select = SNAP_ALL, }, @@ -605,7 +605,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op) walk->ar, walk->v3d); walk->v3d_camera_control = ED_view3d_cameracontrol_acquire( - walk->scene, walk->v3d, walk->rv3d, + C, walk->scene, walk->v3d, walk->rv3d, (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0); /* center the mouse */ @@ -687,16 +687,6 @@ static int walkEnd(bContext *C, WalkInfo *walk) return OPERATOR_CANCELLED; } -static bool wm_event_is_last_mousemove(const wmEvent *event) -{ - while ((event = event->next)) { - if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { - return false; - } - } - return true; -} - static void walkEvent(bContext *C, wmOperator *op, WalkInfo *walk, const wmEvent *event) { if (event->type == TIMER && event->customdata == walk->timer) { @@ -749,7 +739,7 @@ static void walkEvent(bContext *C, wmOperator *op, WalkInfo *walk, const wmEvent } else #endif - if (wm_event_is_last_mousemove(event)) { + if (WM_event_is_last_mousemove(event)) { wmWindow *win = CTX_wm_window(C); #ifdef __APPLE__ @@ -931,7 +921,7 @@ static void walkEvent(bContext *C, wmOperator *op, WalkInfo *walk, const wmEvent { float loc[3], nor[3]; float distance; - bool ret = walk_ray_cast(walk->rv3d, walk, loc, nor, &distance); + bool ret = walk_ray_cast(C, walk->rv3d, walk, loc, nor, &distance); /* in case we are teleporting middle way from a jump */ walk->speed_jump = 0.0f; @@ -1211,7 +1201,7 @@ static int walkApply(bContext *C, wmOperator *op, WalkInfo *walk) float difference = -100.0f; float fall_distance; - ret = walk_floor_distance_get(rv3d, walk, dvec, &ray_distance); + ret = walk_floor_distance_get(C, rv3d, walk, dvec, &ray_distance); if (ret) { difference = walk->view_height - ray_distance; @@ -1264,7 +1254,7 @@ static int walkApply(bContext *C, wmOperator *op, WalkInfo *walk) if (t > walk->teleport.duration) { /* check to see if we are landing */ - ret = walk_floor_distance_get(rv3d, walk, dvec, &ray_distance); + ret = walk_floor_distance_get(C, rv3d, walk, dvec, &ray_distance); if (ret) { difference = walk->view_height - ray_distance; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index f6f4566f836..d79babde707 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -66,6 +66,8 @@ #include "BKE_report.h" #include "BKE_workspace.h" +#include "DEG_depsgraph.h" + #include "BIF_glutil.h" #include "GPU_immediate.h" @@ -2623,6 +2625,9 @@ static void constraintTransLim(TransInfo *t, TransData *td) if (td->con) { const bConstraintTypeInfo *ctiLoc = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_LOCLIMIT); const bConstraintTypeInfo *ctiDist = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_DISTLIMIT); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(t->context, &eval_ctx); bConstraintOb cob = {NULL}; bConstraint *con; @@ -2672,7 +2677,7 @@ static void constraintTransLim(TransInfo *t, TransData *td) } /* get constraint targets if needed */ - BKE_constraint_targets_for_solving_get(con, &cob, &targets, ctime); + BKE_constraint_targets_for_solving_get(&eval_ctx, con, &cob, &targets, ctime); /* do constraint */ cti->evaluate_constraint(con, &cob, &targets); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 58e61974df3..052f05fa1e1 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -639,7 +639,7 @@ void restoreBones(TransInfo *t); /*********************** transform_manipulator.c ********** */ -#define MANIPULATOR_AXIS_LINE_WIDTH 2.0 +#define MANIPULATOR_AXIS_LINE_WIDTH 2.0f bool gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 0337b1a376c..b7dc4abc3c5 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -809,7 +809,6 @@ static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen) /* change the chain-length of auto-ik */ void transform_autoik_update(TransInfo *t, short mode) { - const short old_len = t->settings->autoik_chainlen; short *chainlen = &t->settings->autoik_chainlen; bPoseChannel *pchan; @@ -820,12 +819,13 @@ void transform_autoik_update(TransInfo *t, short mode) } else if (mode == -1) { /* mode==-1 is from WHEELMOUSEUP... decreases len */ - if (*chainlen > 0) (*chainlen)--; - } - - /* IK length did not change, skip any updates. */ - if (old_len == *chainlen) { - return; + if (*chainlen > 0) { + (*chainlen)--; + } + else { + /* IK length did not change, skip updates. */ + return; + } } /* sanity checks (don't assume t->poseobj is set, or that it is an armature) */ @@ -850,6 +850,7 @@ static void pose_grab_with_ik_clear(Object *ob) bKinematicConstraint *data; bPoseChannel *pchan; bConstraint *con, *next; + bool relations_changed = false; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { /* clear all temporary lock flags */ @@ -863,6 +864,8 @@ static void pose_grab_with_ik_clear(Object *ob) if (con->type == CONSTRAINT_TYPE_KINEMATIC) { data = con->data; if (data->flag & CONSTRAINT_IK_TEMP) { + relations_changed = true; + /* iTaSC needs clear for removed constraints */ BIK_clear_data(ob->pose); @@ -878,8 +881,10 @@ static void pose_grab_with_ik_clear(Object *ob) } } - /* TODO(sergey): Consider doing partial update only. */ - DEG_relations_tag_update(G.main); + if (relations_changed) { + /* TODO(sergey): Consider doing partial update only. */ + DEG_relations_tag_update(G.main); + } } /* adds the IK to pchan - returns if added */ @@ -2047,7 +2052,7 @@ void flushTransParticles(TransInfo *t) point->flag |= PEP_EDIT_RECALC; } - PE_update_object(scene, sl, OBACT_NEW, 1); + PE_update_object(t->context, scene, sl, OBACT_NEW, 1); } @@ -2678,6 +2683,7 @@ static void createTransEditVerts(TransInfo *t) { TransData *tob = NULL; TransDataExtension *tx = NULL; + EvaluationContext eval_ctx; BMEditMesh *em = BKE_editmesh_from_object(t->obedit); Mesh *me = t->obedit->data; BMesh *bm = em->bm; @@ -2696,6 +2702,10 @@ static void createTransEditVerts(TransInfo *t) int island_info_tot; int *island_vert_map = NULL; + DEG_evaluation_context_init_from_scene(&eval_ctx, + t->scene, t->scene_layer, + DAG_EVAL_VIEWPORT); + /* Even for translation this is needed because of island-orientation, see: T51651. */ const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS); /* Original index of our connected vertex when connected distances are calculated. @@ -2778,7 +2788,7 @@ static void createTransEditVerts(TransInfo *t) if (modifiers_isCorrectableDeformed(t->scene, t->obedit)) { /* check if we can use deform matrices for modifier from the * start up to stack, they are more accurate than quats */ - totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(t->scene, t->obedit, em, &defmats, &defcos); + totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(&eval_ctx, t->scene, t->obedit, em, &defmats, &defcos); } /* if we still have more modifiers, also do crazyspace @@ -2791,7 +2801,7 @@ static void createTransEditVerts(TransInfo *t) if (totleft > 0) #endif { - mappedcos = BKE_crazyspace_get_mapped_editverts(t->scene, t->obedit); + mappedcos = BKE_crazyspace_get_mapped_editverts(&eval_ctx, t->scene, t->obedit); quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats"); BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !prop_mode); if (mappedcos) @@ -5617,6 +5627,9 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) Scene *scene = t->scene; bool constinv; bool skip_invert = false; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(t->context, &eval_ctx); if (t->mode != TFM_DUMMY && ob->rigidbody_object) { float rot[3][3], scale[3]; @@ -5664,11 +5677,11 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) if (skip_invert == false && constinv == false) { ob->transflag |= OB_NO_CONSTRAINTS; /* BKE_object_where_is_calc_time checks this */ - BKE_object_where_is_calc(t->scene, ob); + BKE_object_where_is_calc(&eval_ctx, t->scene, ob); ob->transflag &= ~OB_NO_CONSTRAINTS; } else - BKE_object_where_is_calc(t->scene, ob); + BKE_object_where_is_calc(&eval_ctx, t->scene, ob); td->ob = ob; @@ -5759,10 +5772,14 @@ static void set_trans_object_base_flags(TransInfo *t) DEG_scene_relations_update(G.main, t->scene); /* handle pending update events, otherwise they got copied below */ + EvaluationContext eval_ctx; + DEG_evaluation_context_init_from_scene(&eval_ctx, + t->scene, t->scene_layer, + DAG_EVAL_VIEWPORT); for (base = sl->object_bases.first; base; base = base->next) { if (base->object->recalc & OB_RECALC_ALL) { /* TODO(sergey): Ideally, it's not needed. */ - BKE_object_handle_update(G.main->eval_ctx, t->scene, base->object); + BKE_object_handle_update(&eval_ctx, t->scene, base->object); } } @@ -6149,7 +6166,7 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o */ if (C && (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) { //ED_pose_clear_paths(C, ob); // XXX for now, don't need to clear - ED_pose_recalculate_paths(scene, ob); + ED_pose_recalculate_paths(C, scene, ob); } } else { @@ -6167,27 +6184,23 @@ static void special_aftertrans_update__movieclip(bContext *C, TransInfo *t) { SpaceClip *sc = t->sa->spacedata.first; MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTrackingPlaneTrack *plane_track; ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking); - int framenr = ED_space_clip_get_clip_frame_number(sc); - - for (plane_track = plane_tracks_base->first; + const int framenr = ED_space_clip_get_clip_frame_number(sc); + /* Update coordinates of modified plane tracks. */ + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { bool do_update = false; - if (plane_track->flag & PLANE_TRACK_HIDDEN) { continue; } - do_update |= PLANE_TRACK_VIEW_SELECTED(plane_track) != 0; if (do_update == false) { if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) { int i; for (i = 0; i < plane_track->point_tracksnr; i++) { MovieTrackingTrack *track = plane_track->point_tracks[i]; - if (TRACK_VIEW_SELECTED(sc, track)) { do_update = true; break; @@ -6195,15 +6208,14 @@ static void special_aftertrans_update__movieclip(bContext *C, TransInfo *t) } } } - if (do_update) { BKE_tracking_track_plane_from_existing_motion(plane_track, framenr); } } - - if (t->scene->nodetree) { - /* tracks can be used for stabilization nodes, - * flush update for such nodes */ + if (t->scene->nodetree != NULL) { + /* Tracks can be used for stabilization nodes, + * flush update for such nodes. + */ nodeUpdateID(t->scene->nodetree, &clip->id); WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL); } @@ -6309,10 +6321,13 @@ static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t) * */ void special_aftertrans_update(bContext *C, TransInfo *t) { + EvaluationContext eval_ctx; Object *ob; // short redrawipo=0, resetslowpar=1; const bool canceled = (t->state == TRANS_CANCEL); const bool duplicate = (t->mode == TFM_TIME_DUPLICATE); + + CTX_data_eval_ctx(C, &eval_ctx); /* early out when nothing happened */ if (t->total == 0 || t->mode == TFM_DUMMY) @@ -6652,7 +6667,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) * we need to update the pose otherwise no updates get called during * transform and the auto-ik is not applied. see [#26164] */ struct Object *pose_ob = t->poseobj; - BKE_pose_where_is(t->scene, pose_ob); + BKE_pose_where_is(&eval_ctx, t->scene, pose_ob); } /* set BONE_TRANSFORM flags for autokey, manipulator draw might have changed them */ diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index b360a99f7fc..9c21be26732 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -715,6 +715,9 @@ static void recalcData_spaceclip(TransInfo *t) static void recalcData_objects(TransInfo *t) { Base *base = t->scene_layer->basact; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(t->context, &eval_ctx); if (t->obedit) { if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) { @@ -899,7 +902,7 @@ static void recalcData_objects(TransInfo *t) BIK_clear_data(ob->pose); } else - BKE_pose_where_is(t->scene, ob); + BKE_pose_where_is(&eval_ctx, t->scene, ob); } else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, t->scene_layer, base->object)) { if (t->state != TRANS_CANCEL) { diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 0f5f2f02e84..5b4eebc963f 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -1090,48 +1090,48 @@ static ManipulatorGroup *manipulatorgroup_init(wmManipulatorGroup *mgroup) const wmManipulatorType *wt_dial = WM_manipulatortype_find("MANIPULATOR_WT_dial_3d", true); const wmManipulatorType *wt_prim = WM_manipulatortype_find("MANIPULATOR_WT_primitive_3d", true); -#define MANIPULATOR_NEW_ARROW(v, name, draw_style) { \ - v = WM_manipulator_new_ptr(wt_arrow, mgroup, name, NULL); \ +#define MANIPULATOR_NEW_ARROW(v, draw_style) { \ + v = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); \ RNA_enum_set((v)->ptr, "draw_style", draw_style); \ } ((void)0) -#define MANIPULATOR_NEW_DIAL(v, name, draw_options) { \ - v = WM_manipulator_new_ptr(wt_dial, mgroup, name, NULL); \ +#define MANIPULATOR_NEW_DIAL(v, draw_options) { \ + v = WM_manipulator_new_ptr(wt_dial, mgroup, NULL); \ RNA_enum_set((v)->ptr, "draw_options", draw_options); \ } ((void)0) -#define MANIPULATOR_NEW_PRIM(v, name, draw_style) { \ - v = WM_manipulator_new_ptr(wt_prim, mgroup, name, NULL); \ +#define MANIPULATOR_NEW_PRIM(v, draw_style) { \ + v = WM_manipulator_new_ptr(wt_prim, mgroup, NULL); \ RNA_enum_set((v)->ptr, "draw_style", draw_style); \ } ((void)0) /* add/init widgets - order matters! */ - MANIPULATOR_NEW_DIAL(man->rotate_t, "rotate_t", ED_MANIPULATOR_DIAL_DRAW_FLAG_FILL); + MANIPULATOR_NEW_DIAL(man->rotate_t, ED_MANIPULATOR_DIAL_DRAW_FLAG_FILL); - MANIPULATOR_NEW_DIAL(man->scale_c, "scale_c", ED_MANIPULATOR_DIAL_DRAW_FLAG_NOP); + MANIPULATOR_NEW_DIAL(man->scale_c, ED_MANIPULATOR_DIAL_DRAW_FLAG_NOP); - MANIPULATOR_NEW_ARROW(man->scale_x, "scale_x", ED_MANIPULATOR_ARROW_STYLE_BOX); - MANIPULATOR_NEW_ARROW(man->scale_y, "scale_y", ED_MANIPULATOR_ARROW_STYLE_BOX); - MANIPULATOR_NEW_ARROW(man->scale_z, "scale_z", ED_MANIPULATOR_ARROW_STYLE_BOX); + MANIPULATOR_NEW_ARROW(man->scale_x, ED_MANIPULATOR_ARROW_STYLE_BOX); + MANIPULATOR_NEW_ARROW(man->scale_y, ED_MANIPULATOR_ARROW_STYLE_BOX); + MANIPULATOR_NEW_ARROW(man->scale_z, ED_MANIPULATOR_ARROW_STYLE_BOX); - MANIPULATOR_NEW_PRIM(man->scale_xy, "scale_xy", ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); - MANIPULATOR_NEW_PRIM(man->scale_yz, "scale_yz", ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); - MANIPULATOR_NEW_PRIM(man->scale_zx, "scale_zx", ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); + MANIPULATOR_NEW_PRIM(man->scale_xy, ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); + MANIPULATOR_NEW_PRIM(man->scale_yz, ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); + MANIPULATOR_NEW_PRIM(man->scale_zx, ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); - MANIPULATOR_NEW_DIAL(man->rotate_x, "rotate_x", ED_MANIPULATOR_DIAL_DRAW_FLAG_CLIP); - MANIPULATOR_NEW_DIAL(man->rotate_y, "rotate_y", ED_MANIPULATOR_DIAL_DRAW_FLAG_CLIP); - MANIPULATOR_NEW_DIAL(man->rotate_z, "rotate_z", ED_MANIPULATOR_DIAL_DRAW_FLAG_CLIP); + MANIPULATOR_NEW_DIAL(man->rotate_x, ED_MANIPULATOR_DIAL_DRAW_FLAG_CLIP); + MANIPULATOR_NEW_DIAL(man->rotate_y, ED_MANIPULATOR_DIAL_DRAW_FLAG_CLIP); + MANIPULATOR_NEW_DIAL(man->rotate_z, ED_MANIPULATOR_DIAL_DRAW_FLAG_CLIP); /* init screen aligned widget last here, looks better, behaves better */ - MANIPULATOR_NEW_DIAL(man->rotate_c, "rotate_c", ED_MANIPULATOR_DIAL_DRAW_FLAG_NOP); + MANIPULATOR_NEW_DIAL(man->rotate_c, ED_MANIPULATOR_DIAL_DRAW_FLAG_NOP); - MANIPULATOR_NEW_DIAL(man->translate_c, "translate_c", ED_MANIPULATOR_DIAL_DRAW_FLAG_NOP); + MANIPULATOR_NEW_DIAL(man->translate_c, ED_MANIPULATOR_DIAL_DRAW_FLAG_NOP); - MANIPULATOR_NEW_ARROW(man->translate_x, "translate_x", ED_MANIPULATOR_ARROW_STYLE_NORMAL); - MANIPULATOR_NEW_ARROW(man->translate_y, "translate_y", ED_MANIPULATOR_ARROW_STYLE_NORMAL); - MANIPULATOR_NEW_ARROW(man->translate_z, "translate_z", ED_MANIPULATOR_ARROW_STYLE_NORMAL); + MANIPULATOR_NEW_ARROW(man->translate_x, ED_MANIPULATOR_ARROW_STYLE_NORMAL); + MANIPULATOR_NEW_ARROW(man->translate_y, ED_MANIPULATOR_ARROW_STYLE_NORMAL); + MANIPULATOR_NEW_ARROW(man->translate_z, ED_MANIPULATOR_ARROW_STYLE_NORMAL); - MANIPULATOR_NEW_PRIM(man->translate_xy, "translate_xy", ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); - MANIPULATOR_NEW_PRIM(man->translate_yz, "translate_yz", ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); - MANIPULATOR_NEW_PRIM(man->translate_zx, "translate_zx", ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); + MANIPULATOR_NEW_PRIM(man->translate_xy, ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); + MANIPULATOR_NEW_PRIM(man->translate_yz, ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); + MANIPULATOR_NEW_PRIM(man->translate_zx, ED_MANIPULATOR_PRIMITIVE_STYLE_PLANE); return man; } @@ -1140,7 +1140,8 @@ static ManipulatorGroup *manipulatorgroup_init(wmManipulatorGroup *mgroup) * Custom handler for manipulator widgets */ static void manipulator_modal( - bContext *C, wmManipulator *widget, const wmEvent *UNUSED(event), const int UNUSED(flag)) + bContext *C, wmManipulator *widget, const wmEvent *UNUSED(event), + eWM_ManipulatorTweak UNUSED(tweak_flag)) { const ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); diff --git a/source/blender/editors/transform/transform_manipulator2d.c b/source/blender/editors/transform/transform_manipulator2d.c index 104675cb1a8..dd6fe762423 100644 --- a/source/blender/editors/transform/transform_manipulator2d.c +++ b/source/blender/editors/transform/transform_manipulator2d.c @@ -134,8 +134,8 @@ static ManipulatorGroup2D *manipulatorgroup2d_init(wmManipulatorGroup *mgroup) ManipulatorGroup2D *man = MEM_callocN(sizeof(ManipulatorGroup2D), __func__); - man->translate_x = WM_manipulator_new_ptr(wt_arrow, mgroup, "translate_x", NULL); - man->translate_y = WM_manipulator_new_ptr(wt_arrow, mgroup, "translate_y", NULL); + man->translate_x = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); + man->translate_y = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL); return man; } @@ -168,7 +168,8 @@ BLI_INLINE void manipulator2d_origin_to_region(ARegion *ar, float *r_origin) * Custom handler for manipulator widgets */ static void manipulator2d_modal( - bContext *C, wmManipulator *widget, const wmEvent *UNUSED(event), const int UNUSED(flag)) + bContext *C, wmManipulator *widget, const wmEvent *UNUSED(event), + eWM_ManipulatorTweak UNUSED(tweak_flag)) { ARegion *ar = CTX_wm_region(C); float origin[3]; diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index dba442259d1..affa5183ada 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -1050,6 +1050,8 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", TABKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0); RNA_string_set(kmi->ptr, "data_path", "tool_settings.snap_element"); + /* Will fall-through to texture-space transform. */ + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_transform_axis_target", TKEY, KM_PRESS, KM_SHIFT, 0); kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, TKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "texture_space", true); diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 1181f584313..906a6ce20ef 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1197,7 +1197,7 @@ bool snapObjectsTransform( float r_loc[3], float r_no[3]) { return ED_transform_snap_object_project_view3d_ex( - t->tsnap.object_context, + t->context, t->tsnap.object_context, t->scene->toolsettings->snap_mode, &(const struct SnapObjectParams){ .snap_select = t->tsnap.modeSelect, @@ -1211,7 +1211,7 @@ bool snapObjectsTransform( /******************** PEELING *********************************/ bool peelObjectsSnapContext( - SnapObjectContext *sctx, + const bContext *C, SnapObjectContext *sctx, const float mval[2], const struct SnapObjectParams *params, const bool use_peel_object, @@ -1220,7 +1220,7 @@ bool peelObjectsSnapContext( { ListBase depths_peel = {0}; ED_transform_snap_object_project_all_view3d_ex( - sctx, + C, sctx, params, mval, -1.0f, false, &depths_peel); @@ -1287,7 +1287,7 @@ bool peelObjectsTransform( float r_loc[3], float r_no[3], float *r_thickness) { return peelObjectsSnapContext( - t->tsnap.object_context, + t->context, t->tsnap.object_context, mval, &(const struct SnapObjectParams){ .snap_select = t->tsnap.modeSelect, diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index bdefd169f22..49f8a41d743 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -51,6 +51,9 @@ #include "BKE_editmesh.h" #include "BKE_main.h" #include "BKE_tracking.h" +#include "BKE_context.h" + +#include "DEG_depsgraph.h" #include "ED_transform.h" #include "ED_transform_snap_object_context.h" @@ -140,7 +143,7 @@ struct SnapObjectContext { * \{ */ -typedef void(*IterSnapObjsCallback)(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data); +typedef void(*IterSnapObjsCallback)(const bContext *C, SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data); /** * Walks through all objects in the scene to create the list of objets to snap. @@ -150,6 +153,7 @@ typedef void(*IterSnapObjsCallback)(SnapObjectContext *sctx, bool is_obedit, Obj * \param obedit : Object Edited to use its coordinates of BMesh(if any) to do the snapping. */ static void iter_snap_objects( + const bContext *C, SnapObjectContext *sctx, const SnapSelect snap_select, Object *obedit, @@ -163,7 +167,7 @@ static void iter_snap_objects( * To solve that problem, we do it first as an exception. * */ if (base_act && base_act->object && base_act->object->mode & OB_MODE_PARTICLE_EDIT) { - sob_callback(sctx, false, base_act->object, base_act->object->obmat, data); + sob_callback(C, sctx, false, base_act->object, base_act->object->obmat, data); } for (Base *base = sctx->scene_layer->object_bases.first; base != NULL; base = base->next) { @@ -178,13 +182,13 @@ static void iter_snap_objects( ListBase *lb = object_duplilist(sctx->bmain->eval_ctx, sctx->scene, obj); for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { use_obedit = obedit && dupli_ob->ob->data == obedit->data; - sob_callback(sctx, use_obedit, use_obedit ? obedit : dupli_ob->ob, dupli_ob->mat, data); + sob_callback(C, sctx, use_obedit, use_obedit ? obedit : dupli_ob->ob, dupli_ob->mat, data); } free_object_duplilist(lb); } use_obedit = obedit && obj->data == obedit->data; - sob_callback(sctx, use_obedit, use_obedit ? obedit : obj, obj->obmat, data); + sob_callback(C, sctx, use_obedit, use_obedit ? obedit : obj, obj->obmat, data); } } } @@ -365,7 +369,7 @@ static void raycast_all_cb(void *userdata, int index, const BVHTreeRay *ray, BVH static bool raycastDerivedMesh( SnapObjectContext *sctx, - const float ray_orig[3], const float ray_start[3], const float ray_dir[3], const float depth_range[2], + const float ray_start[3], const float ray_dir[3], Object *ob, DerivedMesh *dm, float obmat[4][4], const unsigned int ob_index, /* read/write args */ float *ray_depth, @@ -483,18 +487,11 @@ static bool raycastDerivedMesh( * because even in the Orthografic view, in some cases, * the ray can start inside the object (see T50486) */ if (len_diff > 400.0f) { - float ray_org_local[3]; - - copy_v3_v3(ray_org_local, ray_orig); - mul_m4_v3(imat, ray_org_local); - /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with * very far away ray_start values (as returned in case of ortho view3d), see T38358. */ len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */ - madd_v3_v3v3fl( - ray_start_local, ray_org_local, ray_normal_local, - len_diff + depth_range[0] * local_scale); + madd_v3_v3fl(ray_start_local, ray_normal_local, len_diff); local_depth -= len_diff; } else { @@ -556,7 +553,7 @@ static bool raycastDerivedMesh( static bool raycastEditMesh( SnapObjectContext *sctx, - const float ray_orig[3], const float ray_start[3], const float ray_dir[3], const float depth_range[2], + const float ray_start[3], const float ray_dir[3], Object *ob, BMEditMesh *em, float obmat[4][4], const unsigned int ob_index, /* read/write args */ float *ray_depth, @@ -570,8 +567,7 @@ static bool raycastEditMesh( } SnapObjectData_EditMesh *sod = NULL; - - BVHTreeFromEditMesh *treedata; + BVHTreeFromEditMesh *treedata = NULL; void **sod_p; if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) { @@ -647,18 +643,11 @@ static bool raycastEditMesh( * because even in the Orthografic view, in some cases, * the ray can start inside the object (see T50486) */ if (len_diff > 400.0f) { - float ray_org_local[3]; - - copy_v3_v3(ray_org_local, ray_orig); - mul_m4_v3(imat, ray_org_local); - /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with * very far away ray_start values (as returned in case of ortho view3d), see T38358. */ len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */ - madd_v3_v3v3fl( - ray_start_local, ray_org_local, ray_normal_local, - len_diff + depth_range[0] * local_scale); + madd_v3_v3fl(ray_start_local, ray_normal_local, len_diff); local_depth -= len_diff; } else len_diff = 0.0f; @@ -724,8 +713,8 @@ static bool raycastEditMesh( * \note Duplicate args here are documented at #snapObjectsRay */ static bool raycastObj( - SnapObjectContext *sctx, - const float ray_orig[3], const float ray_start[3], const float ray_dir[3], const float depth_range[2], + const bContext *C, SnapObjectContext *sctx, + const float ray_start[3], const float ray_dir[3], Object *ob, float obmat[4][4], const unsigned int ob_index, bool use_obedit, /* read/write args */ @@ -735,8 +724,11 @@ static bool raycastObj( Object **r_ob, float r_obmat[4][4], ListBase *r_hit_list) { + EvaluationContext eval_ctx; bool retval = false; + CTX_data_eval_ctx(C, &eval_ctx); + if (ob->type == OB_MESH) { BMEditMesh *em; @@ -744,7 +736,7 @@ static bool raycastObj( em = BKE_editmesh_from_object(ob); retval = raycastEditMesh( sctx, - ray_orig, ray_start, ray_dir, depth_range, + ray_start, ray_dir, ob, em, obmat, ob_index, ray_depth, r_loc, r_no, r_index, r_hit_list); } @@ -754,14 +746,14 @@ static bool raycastObj( DerivedMesh *dm; em = BKE_editmesh_from_object(ob); if (em) { - editbmesh_get_derived_cage_and_final(sctx->scene, ob, em, CD_MASK_BAREMESH, &dm); + editbmesh_get_derived_cage_and_final(&eval_ctx, sctx->scene, ob, em, CD_MASK_BAREMESH, &dm); } else { - dm = mesh_get_derived_final(sctx->scene, ob, CD_MASK_BAREMESH); + dm = mesh_get_derived_final(&eval_ctx, sctx->scene, ob, CD_MASK_BAREMESH); } retval = raycastDerivedMesh( sctx, - ray_orig, ray_start, ray_dir, depth_range, + ray_start, ray_dir, ob, dm, obmat, ob_index, ray_depth, r_loc, r_no, r_index, r_hit_list); @@ -781,10 +773,8 @@ static bool raycastObj( struct RaycastObjUserData { - const float *ray_orig; const float *ray_start; const float *ray_dir; - const float *depth_range; unsigned int ob_index; /* read/write args */ float *ray_depth; @@ -798,12 +788,12 @@ struct RaycastObjUserData { bool ret; }; -static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data) +static void raycast_obj_cb(const bContext *C, SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data) { struct RaycastObjUserData *dt = data; dt->ret |= raycastObj( - sctx, - dt->ray_orig, dt->ray_start, dt->ray_dir, dt->depth_range, + C, sctx, + dt->ray_start, dt->ray_dir, ob, obmat, dt->ob_index++, is_obedit, dt->ray_depth, dt->r_loc, dt->r_no, dt->r_index, @@ -841,8 +831,8 @@ static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, * */ static bool raycastObjects( - SnapObjectContext *sctx, - const float ray_orig[3], const float ray_start[3], const float ray_dir[3], const float depth_range[2], + const bContext *C, SnapObjectContext *sctx, + const float ray_start[3], const float ray_dir[3], const SnapSelect snap_select, const bool use_object_edit_cage, /* read/write args */ float *ray_depth, @@ -854,10 +844,8 @@ static bool raycastObjects( Object *obedit = use_object_edit_cage ? sctx->scene->obedit : NULL; struct RaycastObjUserData data = { - .ray_orig = ray_orig, .ray_start = ray_start, .ray_dir = ray_dir, - .depth_range = depth_range, .ob_index = 0, .ray_depth = ray_depth, .r_loc = r_loc, @@ -869,7 +857,7 @@ static bool raycastObjects( .ret = false, }; - iter_snap_objects(sctx, snap_select, obedit, raycast_obj_cb, &data); + iter_snap_objects(C, sctx, snap_select, obedit, raycast_obj_cb, &data); return data.ret; } @@ -1840,8 +1828,7 @@ static bool snapEditMesh( float local_scale = normalize_v3(ray_normal_local); SnapObjectData_EditMesh *sod = NULL; - - BVHTreeFromEditMesh *treedata; + BVHTreeFromEditMesh *treedata = NULL; void **sod_p; if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) { @@ -1963,7 +1950,7 @@ static bool snapEditMesh( * \note Duplicate args here are documented at #snapObjectsRay */ static bool snapObject( - SnapObjectContext *sctx, SnapData *snapdata, + const bContext *C, SnapObjectContext *sctx, SnapData *snapdata, Object *ob, float obmat[4][4], bool use_obedit, /* read/write args */ @@ -1972,8 +1959,11 @@ static bool snapObject( float r_loc[3], float r_no[3], Object **r_ob, float r_obmat[4][4]) { + EvaluationContext eval_ctx; bool retval = false; + CTX_data_eval_ctx(C, &eval_ctx); + if (ob->type == OB_MESH) { BMEditMesh *em; @@ -1990,10 +1980,10 @@ static bool snapObject( DerivedMesh *dm; em = BKE_editmesh_from_object(ob); if (em) { - editbmesh_get_derived_cage_and_final(sctx->scene, ob, em, CD_MASK_BAREMESH, &dm); + editbmesh_get_derived_cage_and_final(&eval_ctx, sctx->scene, ob, em, CD_MASK_BAREMESH, &dm); } else { - dm = mesh_get_derived_final(sctx->scene, ob, CD_MASK_BAREMESH); + dm = mesh_get_derived_final(&eval_ctx, sctx->scene, ob, CD_MASK_BAREMESH); } retval = snapDerivedMesh( sctx, snapdata, ob, dm, obmat, @@ -2057,11 +2047,11 @@ struct SnapObjUserData { bool ret; }; -static void sanp_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data) +static void sanp_obj_cb(const bContext *C, SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data) { struct SnapObjUserData *dt = data; dt->ret |= snapObject( - sctx, dt->snapdata, + C, sctx, dt->snapdata, ob, obmat, is_obedit, /* read/write args */ dt->ray_depth, dt->dist_px, @@ -2100,7 +2090,7 @@ static void sanp_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, flo * */ static bool snapObjectsRay( - SnapObjectContext *sctx, SnapData *snapdata, + const bContext *C, SnapObjectContext *sctx, SnapData *snapdata, const SnapSelect snap_select, const bool use_object_edit_cage, /* read/write args */ float *ray_depth, float *dist_px, @@ -2121,7 +2111,7 @@ static bool snapObjectsRay( .ret = false, }; - iter_snap_objects(sctx, snap_select, obedit, sanp_obj_cb, &data); + iter_snap_objects(C, sctx, snap_select, obedit, sanp_obj_cb, &data); return data.ret; } @@ -2217,18 +2207,16 @@ void ED_transform_snap_object_context_set_editmesh_callbacks( } bool ED_transform_snap_object_project_ray_ex( - SnapObjectContext *sctx, + const bContext *C, SnapObjectContext *sctx, const struct SnapObjectParams *params, const float ray_start[3], const float ray_normal[3], float *ray_depth, float r_loc[3], float r_no[3], int *r_index, Object **r_ob, float r_obmat[4][4]) { - const float depth_range[2] = {0.0f, FLT_MAX}; - return raycastObjects( - sctx, - ray_start, ray_start, ray_normal, depth_range, + C, sctx, + ray_start, ray_normal, params->snap_select, params->use_object_edit_cage, ray_depth, r_loc, r_no, r_index, r_ob, r_obmat, NULL); } @@ -2241,13 +2229,12 @@ bool ED_transform_snap_object_project_ray_ex( * \param r_hit_list: List of #SnapObjectHitDepth (caller must free). */ bool ED_transform_snap_object_project_ray_all( - SnapObjectContext *sctx, + const bContext *C, SnapObjectContext *sctx, const struct SnapObjectParams *params, const float ray_start[3], const float ray_normal[3], float ray_depth, bool sort, ListBase *r_hit_list) { - const float depth_range[2] = {0.0f, FLT_MAX}; if (ray_depth == -1.0f) { ray_depth = BVH_RAYCAST_DIST_MAX; } @@ -2257,8 +2244,8 @@ bool ED_transform_snap_object_project_ray_all( #endif bool retval = raycastObjects( - sctx, - ray_start, ray_start, ray_normal, depth_range, + C, sctx, + ray_start, ray_normal, params->snap_select, params->use_object_edit_cage, &ray_depth, NULL, NULL, NULL, NULL, NULL, r_hit_list); @@ -2283,7 +2270,7 @@ bool ED_transform_snap_object_project_ray_all( * \return Snap success */ static bool transform_snap_context_project_ray_impl( - SnapObjectContext *sctx, + const bContext *C, SnapObjectContext *sctx, const struct SnapObjectParams *params, const float ray_start[3], const float ray_normal[3], float *ray_depth, float r_co[3], float r_no[3]) @@ -2292,7 +2279,7 @@ static bool transform_snap_context_project_ray_impl( /* try snap edge, then face if it fails */ ret = ED_transform_snap_object_project_ray_ex( - sctx, + C, sctx, params, ray_start, ray_normal, ray_depth, r_co, r_no, NULL, @@ -2302,7 +2289,7 @@ static bool transform_snap_context_project_ray_impl( } bool ED_transform_snap_object_project_ray( - SnapObjectContext *sctx, + const bContext *C, SnapObjectContext *sctx, const struct SnapObjectParams *params, const float ray_origin[3], const float ray_direction[3], float *ray_depth, float r_co[3], float r_no[3]) @@ -2314,14 +2301,14 @@ bool ED_transform_snap_object_project_ray( } return transform_snap_context_project_ray_impl( - sctx, + C, sctx, params, ray_origin, ray_direction, ray_depth, r_co, r_no); } static bool transform_snap_context_project_view3d_mixed_impl( - SnapObjectContext *sctx, + const bContext *C, SnapObjectContext *sctx, const unsigned short snap_to_flag, const struct SnapObjectParams *params, const float mval[2], float *dist_px, @@ -2345,7 +2332,7 @@ static bool transform_snap_context_project_view3d_mixed_impl( *dist_px = dist_px_orig; } if (ED_transform_snap_object_project_view3d( - sctx, + C, sctx, elem_type[i], params, mval, dist_px, &ray_depth, r_co, r_no)) @@ -2362,7 +2349,7 @@ static bool transform_snap_context_project_view3d_mixed_impl( for (int i = 0; i < 3; i++) { if (snap_to_flag & (1 << i)) { if (ED_transform_snap_object_project_view3d( - sctx, + C, sctx, elem_type[i], params, mval, dist_px, &ray_depth, r_co, r_no)) @@ -2391,7 +2378,7 @@ static bool transform_snap_context_project_view3d_mixed_impl( * \return Snap success */ bool ED_transform_snap_object_project_view3d_mixed( - SnapObjectContext *sctx, + const bContext *C, SnapObjectContext *sctx, const unsigned short snap_to_flag, const struct SnapObjectParams *params, const float mval_fl[2], float *dist_px, @@ -2399,14 +2386,14 @@ bool ED_transform_snap_object_project_view3d_mixed( float r_co[3], float r_no[3]) { return transform_snap_context_project_view3d_mixed_impl( - sctx, + C, sctx, snap_to_flag, params, mval_fl, dist_px, use_depth, r_co, r_no); } bool ED_transform_snap_object_project_view3d_ex( - SnapObjectContext *sctx, + const bContext *C, SnapObjectContext *sctx, const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], float *dist_px, @@ -2440,8 +2427,8 @@ bool ED_transform_snap_object_project_view3d_ex( if (snap_to == SCE_SNAP_MODE_FACE) { return raycastObjects( - sctx, - ray_origin, ray_start, ray_normal, depth_range, + C, sctx, + ray_start, ray_normal, params->snap_select, params->use_object_edit_cage, ray_depth, r_loc, r_no, r_index, NULL, NULL, NULL); } @@ -2452,14 +2439,14 @@ bool ED_transform_snap_object_project_view3d_ex( ray_origin, ray_start, ray_normal, depth_range); return snapObjectsRay( - sctx, &snapdata, + C, sctx, &snapdata, params->snap_select, params->use_object_edit_cage, ray_depth, dist_px, r_loc, r_no, NULL, NULL); } } bool ED_transform_snap_object_project_view3d( - SnapObjectContext *sctx, + const bContext *C, SnapObjectContext *sctx, const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], float *dist_px, @@ -2467,7 +2454,7 @@ bool ED_transform_snap_object_project_view3d( float r_loc[3], float r_no[3]) { return ED_transform_snap_object_project_view3d_ex( - sctx, + C, sctx, snap_to, params, mval, dist_px, @@ -2479,7 +2466,7 @@ bool ED_transform_snap_object_project_view3d( * see: #ED_transform_snap_object_project_ray_all */ bool ED_transform_snap_object_project_all_view3d_ex( - SnapObjectContext *sctx, + const bContext *C, SnapObjectContext *sctx, const struct SnapObjectParams *params, const float mval[2], float ray_depth, bool sort, @@ -2495,7 +2482,7 @@ bool ED_transform_snap_object_project_all_view3d_ex( } return ED_transform_snap_object_project_ray_all( - sctx, + C, sctx, params, ray_start, ray_normal, ray_depth, sort, r_hit_list); diff --git a/source/blender/gpu/GPU_select.h b/source/blender/gpu/GPU_select.h index cf5b8bf7d8f..0617d58f3b6 100644 --- a/source/blender/gpu/GPU_select.h +++ b/source/blender/gpu/GPU_select.h @@ -56,4 +56,7 @@ void GPU_select_cache_begin(void); void GPU_select_cache_load_id(void); void GPU_select_cache_end(void); +/* utilities */ +const uint *GPU_select_buffer_near(const uint *buffer, int hits); + #endif diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index fb2e271f9a2..e918b70ec7c 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -78,7 +78,7 @@ typedef struct { static size_t gpu_buffer_size_from_type(DerivedMesh *dm, GPUBufferType type); -const GPUBufferTypeSettings gpu_buffer_type_settings[] = { +static const GPUBufferTypeSettings gpu_buffer_type_settings[] = { /* vertex */ {GL_ARRAY_BUFFER, 3}, /* normal */ diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c index cb782358f91..5a64b0ec781 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.c @@ -558,8 +558,14 @@ void GPU_framebuffer_recursive_downsample( attachment = GL_COLOR_ATTACHMENT0; /* last bound prevails here, better allow explicit control here too */ - glDrawBuffer(GL_COLOR_ATTACHMENT0); - glReadBuffer(GL_COLOR_ATTACHMENT0); + if (GPU_texture_depth(tex)) { + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + } + else { + glDrawBuffer(GL_COLOR_ATTACHMENT0); + glReadBuffer(GL_COLOR_ATTACHMENT0); + } for (int i=1; i < num_iter+1 && (current_dim[0] > 1 && current_dim[1] > 1); i++) { diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c index a4e54d15034..e6923d38110 100644 --- a/source/blender/gpu/intern/gpu_immediate_util.c +++ b/source/blender/gpu/intern/gpu_immediate_util.c @@ -55,7 +55,7 @@ static void imm_draw_circle(Gwn_PrimType prim_type, const uint shdr_pos, float x { immBegin(prim_type, nsegments); for (int i = 0; i < nsegments; ++i) { - const float angle = 2 * M_PI * ((float)i / (float)nsegments); + const float angle = (float)(2 * M_PI) * ((float)i / (float)nsegments); immVertex2f(shdr_pos, x + rad * cosf(angle), y + rad * sinf(angle)); } immEnd(); @@ -99,7 +99,7 @@ static void imm_draw_disk_partial( float rad_inner, float rad_outer, int nsegments, float start, float sweep) { /* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */ - const float angle_start = -(DEG2RADF(start)) + (M_PI / 2); + const float angle_start = -(DEG2RADF(start)) + (float)(M_PI / 2); const float angle_end = -(DEG2RADF(sweep) - angle_start); nsegments += 1; immBegin(prim_type, nsegments * 2); @@ -141,7 +141,7 @@ static void imm_draw_circle_3D( { immBegin(prim_type, nsegments); for (int i = 0; i < nsegments; ++i) { - float angle = 2 * M_PI * ((float)i / (float)nsegments); + float angle = (float)(2 * M_PI) * ((float)i / (float)nsegments); immVertex3f(pos, x + rad * cosf(angle), y + rad * sinf(angle), 0.0f); } immEnd(); @@ -221,8 +221,8 @@ void imm_draw_cylinder_fill_normal_3d( { immBegin(GWN_PRIM_TRIS, 6 * slices * stacks); for (int i = 0; i < slices; ++i) { - const float angle1 = 2 * M_PI * ((float)i / (float)slices); - const float angle2 = 2 * M_PI * ((float)(i + 1) / (float)slices); + const float angle1 = (float)(2 * M_PI) * ((float)i / (float)slices); + const float angle2 = (float)(2 * M_PI) * ((float)(i + 1) / (float)slices); const float cos1 = cosf(angle1); const float sin1 = sinf(angle1); const float cos2 = cosf(angle2); @@ -272,8 +272,8 @@ void imm_draw_cylinder_wire_3d(unsigned int pos, float base, float top, float he { immBegin(GWN_PRIM_LINES, 6 * slices * stacks); for (int i = 0; i < slices; ++i) { - const float angle1 = 2 * M_PI * ((float)i / (float)slices); - const float angle2 = 2 * M_PI * ((float)(i + 1) / (float)slices); + const float angle1 = (float)(2 * M_PI) * ((float)i / (float)slices); + const float angle2 = (float)(2 * M_PI) * ((float)(i + 1) / (float)slices); const float cos1 = cosf(angle1); const float sin1 = sinf(angle1); const float cos2 = cosf(angle2); @@ -309,8 +309,8 @@ void imm_draw_cylinder_fill_3d(unsigned int pos, float base, float top, float he { immBegin(GWN_PRIM_TRIS, 6 * slices * stacks); for (int i = 0; i < slices; ++i) { - const float angle1 = 2 * M_PI * ((float)i / (float)slices); - const float angle2 = 2 * M_PI * ((float)(i + 1) / (float)slices); + const float angle1 = (float)(2 * M_PI) * ((float)i / (float)slices); + const float angle2 = (float)(2 * M_PI) * ((float)(i + 1) / (float)slices); const float cos1 = cosf(angle1); const float sin1 = sinf(angle1); const float cos2 = cosf(angle2); diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c index 162a605ef3d..153cf5f1e97 100644 --- a/source/blender/gpu/intern/gpu_select.c +++ b/source/blender/gpu/intern/gpu_select.c @@ -227,3 +227,29 @@ bool GPU_select_is_cached(void) { return g_select_state.use_cache && gpu_select_pick_is_cached(); } + + +/* ---------------------------------------------------------------------------- + * Utilities + */ + +/** + * Helper function, nothing special but avoids doing inline since hit's aren't sorted by depth + * and purpose of 4x buffer indices isn't so clear. + * + * Note that comparing depth as uint is fine. + */ +const uint *GPU_select_buffer_near(const uint *buffer, int hits) +{ + const uint *buffer_near = NULL; + uint depth_min = (uint)-1; + for (int i = 0; i < hits; i++) { + if (buffer[1] < depth_min) { + BLI_assert(buffer[3] != -1); + depth_min = buffer[1]; + buffer_near = buffer; + } + buffer += 4; + } + return buffer_near; +} diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl index b86d6fd70fe..c49832bf9b4 100644 --- a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl @@ -2,7 +2,7 @@ uniform mat4 ModelViewProjectionMatrix; const float pixel_fudge = sqrt(2.0); -const float outline_width = 1.25 * pixel_fudge; +const float outline_width = 1.15 * pixel_fudge; in vec2 pos; in float size; diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 81f70332876..416907c8453 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -2663,6 +2663,8 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result) { #ifdef EEVEE_ENGINE vec3 L = eevee_surface_diffuse_lit(N, vec3(1.0), 1.0); + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = Closure(L * color.rgb, 1.0, vec4(0.0), normal_encode(N, viewCameraVec), -1); #else /* ambient light */ vec3 L = vec3(0.2); @@ -2675,15 +2677,19 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result) float bsdf = max(dot(N, light_position), 0.0); L += light_diffuse * bsdf; } -#endif result = Closure(L * color.rgb, 1.0); +#endif } -void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out Closure result) +void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Closure result) { #ifdef EEVEE_ENGINE - vec3 L = eevee_surface_glossy_lit(N, vec3(1.0), roughness, 1.0); + vec3 ssr_spec; + roughness = sqrt(roughness); + vec3 L = eevee_surface_glossy_lit(N, vec3(1.0), roughness, 1.0, int(ssr_id), ssr_spec); + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = Closure(L * color.rgb, 1.0, vec4(ssr_spec * color.rgb, roughness), normal_encode(vN, viewCameraVec), int(ssr_id)); #else /* ambient light */ vec3 L = vec3(0.2); @@ -2702,9 +2708,9 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out Closure result) bsdf += 0.5 * max(dot(N, light_position), 0.0); L += light_specular * bsdf; } -#endif result = Closure(L * color.rgb, 1.0); +#endif } void node_bsdf_anisotropic( @@ -2724,6 +2730,7 @@ void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure r node_bsdf_diffuse(color, 0.0, N, result); } +#ifndef EEVEE_ENGINE void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out Closure result) @@ -2821,16 +2828,19 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad result = Closure(L, 1.0); } +#endif void node_bsdf_principled_simple(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, - float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out Closure result) + float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, out Closure result) { #ifdef EEVEE_ENGINE - vec3 diffuse, f0; + vec3 diffuse, f0, ssr_spec; convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0); - result = Closure(eevee_surface_lit(N, diffuse, f0, roughness, 1.0), 1.0); + vec3 L = eevee_surface_lit(N, diffuse, f0, roughness, 1.0, int(ssr_id), ssr_spec); + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = Closure(L, 1.0, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id)); #else node_bsdf_principled(base_color, subsurface, subsurface_radius, subsurface_color, metallic, specular, specular_tint, roughness, anisotropic, anisotropic_rotation, sheen, sheen_tint, clearcoat, @@ -2840,10 +2850,10 @@ void node_bsdf_principled_simple(vec4 base_color, float subsurface, vec3 subsurf void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, - float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out Closure result) + float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, out Closure result) { #ifdef EEVEE_ENGINE - vec3 diffuse, f0; + vec3 diffuse, f0, ssr_spec; convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0); clearcoat *= 0.25; @@ -2865,13 +2875,16 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs N = tangent_to_world(Ht, N, Y, X); if (dot(N, cameraVec) > 0) { - surface_color.rgb += eevee_surface_clearcoat_lit(N, diffuse, f0, sqrt(min(ax, ay)), CN, clearcoat, clearcoat_roughness, 1.0); + surface_color.rgb += eevee_surface_clearcoat_lit(N, diffuse, f0, sqrt(min(ax, ay)), CN, clearcoat, clearcoat_roughness, 1.0, ssr_id); surface_color.a += 1.0; } } result = Closure(surface_color.rgb / surface_color.a, 1.0); #else - result = Closure(eevee_surface_clearcoat_lit(N, diffuse, f0, roughness, CN, clearcoat, clearcoat_roughness, 1.0), 1.0); + + vec3 L = eevee_surface_clearcoat_lit(N, diffuse, f0, roughness, CN, clearcoat, clearcoat_roughness, 1.0, int(ssr_id), ssr_spec); + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = Closure(L, 1.0, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id)); #endif #else @@ -2905,6 +2918,8 @@ void node_subsurface_scattering( node_bsdf_diffuse(color, 0.0, N, result); } +/* Unsupported for now */ +#ifndef EEVEE_ENGINE void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv, vec3 tangent, out Closure result) { result = Closure(color.rgb, color.a); @@ -2919,6 +2934,8 @@ void node_ambient_occlusion(vec4 color, out Closure result) { result = Closure(color.rgb, color.a); } +#endif /* EEVEE_ENGINE */ + #endif /* VOLUMETRICS */ /* emission */ @@ -2927,7 +2944,11 @@ void node_emission(vec4 color, float strength, vec3 N, out Closure result) { #ifndef VOLUMETRICS color *= strength; +#ifdef EEVEE_ENGINE + result = Closure(color.rgb, color.a, vec4(0.0), normal_encode(N, viewCameraVec), -1); +#else result = Closure(color.rgb, color.a); +#endif #else result = Closure(vec3(0.0), vec3(0.0), color.rgb * strength, 0.0); #endif @@ -2952,7 +2973,11 @@ void node_background(vec4 color, float strength, out Closure result) { #ifndef VOLUMETRICS color *= strength; +#ifdef EEVEE_ENGINE + result = Closure(color.rgb, color.a, vec4(0.0), vec2(0.0), -1); +#else result = Closure(color.rgb, color.a); +#endif #else result = CLOSURE_DEFAULT; #endif @@ -3995,7 +4020,11 @@ uniform float backgroundAlpha; void node_output_world(Closure surface, Closure volume, out Closure result) { #ifndef VOLUMETRICS +#ifdef EEVEE_ENGINE + result = Closure(surface.radiance, backgroundAlpha, vec4(0.0), vec2(0.0), -1); +#else result = Closure(surface.radiance, backgroundAlpha); +#endif #else result = volume; #endif /* VOLUMETRICS */ @@ -4013,29 +4042,31 @@ void world_normals_get(out vec3 N) void node_eevee_metallic( vec4 basecol, float metallic, float specular, float roughness, vec4 emissive, float transp, vec3 normal, float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal, - float occlusion, out Closure result) + float occlusion, float ssr_id, out Closure result) { - vec3 diffuse, f0; + vec3 diffuse, f0, ssr_spec; convert_metallic_to_specular(basecol.rgb, metallic, specular, diffuse, f0); - result = Closure(eevee_surface_lit(normal, diffuse, f0, roughness, occlusion) + emissive.rgb, 1.0 - transp); + vec3 L = eevee_surface_lit(normal, diffuse, f0, roughness, occlusion, int(ssr_id), ssr_spec); + vec3 vN = normalize(mat3(ViewMatrix) * normal); + result = Closure(L + emissive.rgb, 1.0 - transp, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id)); } void node_eevee_specular( vec4 diffuse, vec4 specular, float roughness, vec4 emissive, float transp, vec3 normal, float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal, - float occlusion, out Closure result) + float occlusion, float ssr_id, out Closure result) { - result = Closure(eevee_surface_lit(normal, diffuse.rgb, specular.rgb, roughness, occlusion) + emissive.rgb, 1.0 - transp); + vec3 ssr_spec; + + vec3 L = eevee_surface_lit(normal, diffuse.rgb, specular.rgb, roughness, occlusion, int(ssr_id), ssr_spec); + vec3 vN = normalize(mat3(ViewMatrix) * normal); + result = Closure(L + emissive.rgb, 1.0 - transp, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id)); } void node_output_eevee_material(Closure surface, out Closure result) { -#if defined(USE_ALPHA_HASH) || defined(USE_ALPHA_CLIP) || defined(USE_ALPHA_BLEND) result = surface; -#else - result = Closure(surface.radiance, length(viewPosition)); -#endif } #endif /* EEVEE_ENGINE */ diff --git a/source/blender/ikplugin/BIK_api.h b/source/blender/ikplugin/BIK_api.h index 177be074897..8fd13507d3a 100644 --- a/source/blender/ikplugin/BIK_api.h +++ b/source/blender/ikplugin/BIK_api.h @@ -43,6 +43,7 @@ struct bPoseChannel; struct bPose; struct Scene; struct bConstraint; +struct EvaluationContext; enum BIK_ParamType { BIK_PARAM_TYPE_FLOAT = 0, @@ -61,8 +62,8 @@ struct BIK_ParamValue { }; typedef struct BIK_ParamValue BIK_ParamValue; -void BIK_initialize_tree(struct Scene *scene, struct Object *ob, float ctime); -void BIK_execute_tree(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime); +void BIK_initialize_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime); +void BIK_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime); void BIK_release_tree(struct Scene *scene, struct Object *ob, float ctime); void BIK_clear_data(struct bPose *pose); void BIK_clear_cache(struct bPose *pose); diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c index 0f81fb34a63..09a2c3b88ed 100644 --- a/source/blender/ikplugin/intern/ikplugin_api.c +++ b/source/blender/ikplugin/intern/ikplugin_api.c @@ -89,20 +89,20 @@ static IKPlugin *get_plugin(bPose *pose) /*----------------------------------------*/ /* Plugin API */ -void BIK_initialize_tree(Scene *scene, Object *ob, float ctime) +void BIK_initialize_tree(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime) { IKPlugin *plugin = get_plugin(ob->pose); if (plugin && plugin->initialize_tree_func) - plugin->initialize_tree_func(scene, ob, ctime); + plugin->initialize_tree_func(eval_ctx, scene, ob, ctime); } -void BIK_execute_tree(struct Scene *scene, Object *ob, bPoseChannel *pchan, float ctime) +void BIK_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, bPoseChannel *pchan, float ctime) { IKPlugin *plugin = get_plugin(ob->pose); if (plugin && plugin->execute_tree_func) - plugin->execute_tree_func(scene, ob, pchan, ctime); + plugin->execute_tree_func(eval_ctx, scene, ob, pchan, ctime); } void BIK_release_tree(struct Scene *scene, Object *ob, float ctime) diff --git a/source/blender/ikplugin/intern/ikplugin_api.h b/source/blender/ikplugin/intern/ikplugin_api.h index cd32bf26242..07dd601012f 100644 --- a/source/blender/ikplugin/intern/ikplugin_api.h +++ b/source/blender/ikplugin/intern/ikplugin_api.h @@ -41,11 +41,12 @@ extern "C" { struct Object; struct bPoseChannel; struct Scene; +struct EvaluationContext; struct IKPlugin { - void (*initialize_tree_func)(struct Scene *scene, struct Object *ob, float ctime); - void (*execute_tree_func)(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime); + void (*initialize_tree_func)(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime); + void (*execute_tree_func)(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime); void (*release_tree_func)(struct Scene *scene, struct Object *ob, float ctime); void (*remove_armature_func)(struct bPose *pose); void (*clear_cache)(struct bPose *pose); diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index 6ea311b2c7b..1917db24d4f 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -217,9 +217,27 @@ static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[3][3]) // nr = copy_m4_m3(ikmat, ik_mat); if (pchan->parent) - mul_m4_series(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat, ikmat); + mul_m4_m4m4(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat); else - mul_m4_m4m4(pchan->pose_mat, pchan->chan_mat, ikmat); + copy_m4_m4(pchan->pose_mat, pchan->chan_mat); + +#ifdef USE_NONUNIFORM_SCALE + /* apply IK mat, but as if the bones have uniform scale since the IK solver + * is not aware of non-uniform scale */ + float scale[3]; + mat4_to_size(scale, pchan->pose_mat); + normalize_v3_length(pchan->pose_mat[0], scale[1]); + normalize_v3_length(pchan->pose_mat[2], scale[1]); +#endif + + mul_m4_m4m4(pchan->pose_mat, pchan->pose_mat, ikmat); + +#ifdef USE_NONUNIFORM_SCALE + float ik_scale[3]; + mat3_to_size(ik_scale, ik_mat); + normalize_v3_length(pchan->pose_mat[0], scale[0] * ik_scale[0]); + normalize_v3_length(pchan->pose_mat[2], scale[2] * ik_scale[2]); +#endif /* calculate head */ copy_v3_v3(pchan->pose_head, pchan->pose_mat[3]); @@ -234,7 +252,7 @@ static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[3][3]) // nr = /* called from within the core BKE_pose_where_is loop, all animsystems and constraints * were executed & assigned. Now as last we do an IK pass */ -static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree) +static void execute_posetree(struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, PoseTree *tree) { float R_parmat[3][3], identity[3][3]; float iR_parmat[3][3]; @@ -308,6 +326,10 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree) /* change length based on bone size */ length = bone->length * len_v3(R_bonemat[1]); + /* basis must be pure rotation */ + normalize_m3(R_bonemat); + normalize_m3(R_parmat); + /* compute rest basis and its inverse */ copy_m3_m3(rest_basis, bone->bone_mat); transpose_m3_m3(irest_basis, bone->bone_mat); @@ -317,11 +339,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree) mul_m3_m3m3(full_basis, iR_parmat, R_bonemat); mul_m3_m3m3(basis, irest_basis, full_basis); - /* basis must be pure rotation */ - normalize_m3(basis); - /* transform offset into local bone space */ - normalize_m3(iR_parmat); mul_m3_v3(iR_parmat, start); IK_SetTransform(seg, start, rest_basis, basis, length); @@ -376,7 +394,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree) /* 1.0=ctime, we pass on object for auto-ik (owner-type here is object, even though * strictly speaking, it is a posechannel) */ - BKE_constraint_target_matrix_get(scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0); + BKE_constraint_target_matrix_get(eval_ctx, scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0); /* and set and transform goal */ mul_m4_m4m4(goal, goalinv, rootmat); @@ -387,7 +405,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree) /* same for pole vector target */ if (data->poletar) { - BKE_constraint_target_matrix_get(scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0); + BKE_constraint_target_matrix_get(eval_ctx, scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0); if (data->flag & CONSTRAINT_IK_SETANGLE) { /* don't solve IK when we are setting the pole angle */ @@ -516,7 +534,7 @@ static void free_posetree(PoseTree *tree) ///---------------------------------------- /// Plugin API for legacy iksolver -void iksolver_initialize_tree(struct Scene *UNUSED(scene), struct Object *ob, float UNUSED(ctime)) +void iksolver_initialize_tree(struct EvaluationContext *UNUSED(eval_ctx), struct Scene *UNUSED(scene), struct Object *ob, float UNUSED(ctime)) { bPoseChannel *pchan; @@ -527,7 +545,7 @@ void iksolver_initialize_tree(struct Scene *UNUSED(scene), struct Object *ob, fl ob->pose->flag &= ~POSE_WAS_REBUILT; } -void iksolver_execute_tree(struct Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime) +void iksolver_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime) { while (pchan_root->iktree.first) { PoseTree *tree = pchan_root->iktree.first; @@ -540,25 +558,13 @@ void iksolver_execute_tree(struct Scene *scene, Object *ob, bPoseChannel *pchan /* 4. walk over the tree for regular solving */ for (a = 0; a < tree->totchannel; a++) { if (!(tree->pchan[a]->flag & POSE_DONE)) // successive trees can set the flag - BKE_pose_where_is_bone(scene, ob, tree->pchan[a], ctime, 1); + BKE_pose_where_is_bone(eval_ctx, scene, ob, tree->pchan[a], ctime, 1); /* tell blender that this channel was controlled by IK, it's cleared on each BKE_pose_where_is() */ tree->pchan[a]->flag |= POSE_CHAIN; } -#ifdef USE_NONUNIFORM_SCALE - float (*pchan_scale_data)[3] = MEM_mallocN(sizeof(float[3]) * tree->totchannel, __func__); - - for (a = 0; a < tree->totchannel; a++) { - mat4_to_size(pchan_scale_data[a], tree->pchan[a]->pose_mat); - - /* make uniform at y scale since this controls the length */ - normalize_v3_length(tree->pchan[a]->pose_mat[0], pchan_scale_data[a][1]); - normalize_v3_length(tree->pchan[a]->pose_mat[2], pchan_scale_data[a][1]); - } -#endif - /* 5. execute the IK solver */ - execute_posetree(scene, ob, tree); + execute_posetree(eval_ctx, scene, ob, tree); /* 6. apply the differences to the channels, * we need to calculate the original differences first */ @@ -571,14 +577,6 @@ void iksolver_execute_tree(struct Scene *scene, Object *ob, bPoseChannel *pchan where_is_ik_bone(tree->pchan[a], tree->basis_change[a]); } -#ifdef USE_NONUNIFORM_SCALE - for (a = 0; a < tree->totchannel; a++) { - normalize_v3_length(tree->pchan[a]->pose_mat[0], pchan_scale_data[a][0]); - normalize_v3_length(tree->pchan[a]->pose_mat[2], pchan_scale_data[a][2]); - } - MEM_freeN(pchan_scale_data); -#endif - /* 7. and free */ BLI_remlink(&pchan_root->iktree, tree); free_posetree(tree); diff --git a/source/blender/ikplugin/intern/iksolver_plugin.h b/source/blender/ikplugin/intern/iksolver_plugin.h index 07264280a25..b9bdbd892ec 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.h +++ b/source/blender/ikplugin/intern/iksolver_plugin.h @@ -40,8 +40,9 @@ extern "C" { #endif -void iksolver_initialize_tree(struct Scene *scene, struct Object *ob, float ctime); -void iksolver_execute_tree(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan_root, float ctime); +void iksolver_initialize_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime); +void iksolver_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, + struct bPoseChannel *pchan_root, float ctime); #ifdef __cplusplus } diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index d58340965a7..2227747e7a1 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -542,7 +542,7 @@ static void GetJointRotation(KDL::Rotation& boneRot, int type, double *rot) } } -static bool target_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame& current, iTaSC::Frame& next, void *param) +static bool target_callback(struct EvaluationContext *eval_ctx, const iTaSC::Timestamp& timestamp, const iTaSC::Frame& current, iTaSC::Frame& next, void *param) { IK_Target *target = (IK_Target *)param; // compute next target position @@ -550,7 +550,7 @@ static bool target_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Fram bConstraint *constraint = (bConstraint *)target->blenderConstraint; float tarmat[4][4]; - BKE_constraint_target_matrix_get(target->blscene, constraint, 0, CONSTRAINT_OBTYPE_OBJECT, target->owner, tarmat, 1.0); + BKE_constraint_target_matrix_get(eval_ctx, target->blscene, constraint, 0, CONSTRAINT_OBTYPE_OBJECT, target->owner, tarmat, 1.0); // rootmat contains the target pose in world coordinate // if enforce is != 1.0, blend the target position with the end effector position @@ -577,7 +577,7 @@ static bool target_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Fram return true; } -static bool base_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame& current, iTaSC::Frame& next, void *param) +static bool base_callback(struct EvaluationContext *eval_ctx, const iTaSC::Timestamp& timestamp, const iTaSC::Frame& current, iTaSC::Frame& next, void *param) { IK_Scene *ikscene = (IK_Scene *)param; // compute next armature base pose @@ -619,7 +619,7 @@ static bool base_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame& IK_Channel &rootchan = ikscene->channels[0]; // get polar target matrix in world space - BKE_constraint_target_matrix_get(ikscene->blscene, ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0); + BKE_constraint_target_matrix_get(eval_ctx, ikscene->blscene, ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0); // convert to armature space mul_m4_m4m4(polemat, imat, mat); // get the target in world space (was computed before as target object are defined before base object) @@ -863,7 +863,7 @@ static bool joint_callback(const iTaSC::Timestamp& timestamp, iTaSC::ConstraintV } // build array of joint corresponding to IK chain -static int convert_channels(IK_Scene *ikscene, PoseTree *tree, float ctime) +static int convert_channels(struct EvaluationContext *eval_ctx, IK_Scene *ikscene, PoseTree *tree, float ctime) { IK_Channel *ikchan; bPoseChannel *pchan; @@ -880,7 +880,7 @@ static int convert_channels(IK_Scene *ikscene, PoseTree *tree, float ctime) // this is because some of the pose data (e.g. pose head) don't have corresponding // joint angles and can't be applied to the iTaSC armature dynamically if (!(pchan->flag & POSE_DONE)) - BKE_pose_where_is_bone(ikscene->blscene, ikscene->blArmature, pchan, ctime, 1); + BKE_pose_where_is_bone(eval_ctx, ikscene->blscene, ikscene->blArmature, pchan, ctime, 1); // tell blender that this channel was controlled by IK, it's cleared on each BKE_pose_where_is() pchan->flag |= (POSE_DONE | POSE_CHAIN); @@ -1056,7 +1056,7 @@ static void BKE_pose_rest(IK_Scene *ikscene) } } -static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan, float ctime) +static IK_Scene *convert_tree(struct EvaluationContext *eval_ctx, Scene *blscene, Object *ob, bPoseChannel *pchan, float ctime) { PoseTree *tree = (PoseTree *)pchan->iktree.first; PoseTarget *target; @@ -1134,7 +1134,7 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan, f std::vector<double> weights; double weight[3]; // build the array of joints corresponding to the IK chain - convert_channels(ikscene, tree, ctime); + convert_channels(eval_ctx, ikscene, tree, ctime); if (ingame) { // in the GE, set the initial joint angle to match the current pose // this will update the jointArray in ikscene @@ -1397,7 +1397,7 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan, f // we can now add the armature // the armature is based on a moving frame. // initialize with the correct position in case there is no cache - base_callback(iTaSC::Timestamp(), iTaSC::F_identity, initPose, ikscene); + base_callback(eval_ctx, iTaSC::Timestamp(), iTaSC::F_identity, initPose, ikscene); ikscene->base = new iTaSC::MovingFrame(initPose); ikscene->base->setCallback(base_callback, ikscene); std::string armname; @@ -1458,7 +1458,7 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan, f mul_m4_m4m4(iktarget->eeRest, invBaseFrame, mat); iktarget->eeBlend = (!ikscene->polarConstraint && condata->type == CONSTRAINT_IK_COPYPOSE) ? true : false; // use target_callback to make sure the initPose includes enforce coefficient - target_callback(iTaSC::Timestamp(), iTaSC::F_identity, initPose, iktarget); + target_callback(eval_ctx, iTaSC::Timestamp(), iTaSC::F_identity, initPose, iktarget); iktarget->target = new iTaSC::MovingFrame(initPose); iktarget->target->setCallback(target_callback, iktarget); ret = scene->addObject(iktarget->targetName, iktarget->target); @@ -1526,7 +1526,7 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan, f return ikscene; } -static void create_scene(Scene *scene, Object *ob, float ctime) +static void create_scene(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime) { bPoseChannel *pchan; @@ -1537,7 +1537,7 @@ static void create_scene(Scene *scene, Object *ob, float ctime) if (tree) { IK_Data *ikdata = get_ikdata(ob->pose); // convert tree in iTaSC::Scene - IK_Scene *ikscene = convert_tree(scene, ob, pchan, ctime); + IK_Scene *ikscene = convert_tree(eval_ctx, scene, ob, pchan, ctime); if (ikscene) { ikscene->next = ikdata->first; ikdata->first = ikscene; @@ -1576,7 +1576,7 @@ static int init_scene(Object *ob) return 0; } -static void execute_scene(Scene *blscene, IK_Scene *ikscene, bItasc *ikparam, float ctime, float frtime) +static void execute_scene(struct EvaluationContext *eval_ctx, Scene *blscene, IK_Scene *ikscene, bItasc *ikparam, float ctime, float frtime) { int i; IK_Channel *ikchan; @@ -1592,7 +1592,7 @@ static void execute_scene(Scene *blscene, IK_Scene *ikscene, bItasc *ikparam, fl // in animation mode, we must get the bone position from action and constraints for (i = 0, ikchan = ikscene->channels; i < ikscene->numchan; i++, ++ikchan) { if (!(ikchan->pchan->flag & POSE_DONE)) - BKE_pose_where_is_bone(blscene, ikscene->blArmature, ikchan->pchan, ctime, 1); + BKE_pose_where_is_bone(eval_ctx, blscene, ikscene->blArmature, ikchan->pchan, ctime, 1); // tell blender that this channel was controlled by IK, it's cleared on each BKE_pose_where_is() ikchan->pchan->flag |= (POSE_DONE | POSE_CHAIN); ikchan->jointValid = 0; @@ -1647,7 +1647,7 @@ static void execute_scene(Scene *blscene, IK_Scene *ikscene, bItasc *ikparam, fl } } // don't cache if we are reiterating because we don't want to destroy the cache unnecessarily - ikscene->scene->update(timestamp, timestep, numstep, false, !reiterate, simulation); + ikscene->scene->update(eval_ctx, timestamp, timestep, numstep, false, !reiterate, simulation); if (reiterate) { // how many times do we reiterate? for (i = 0; i < ikparam->numiter; i++) { @@ -1656,11 +1656,11 @@ static void execute_scene(Scene *blscene, IK_Scene *ikscene, bItasc *ikparam, fl { break; } - ikscene->scene->update(timestamp, timestep, numstep, true, false, simulation); + ikscene->scene->update(eval_ctx, timestamp, timestep, numstep, true, false, simulation); } if (simulation) { // one more fake iteration to cache - ikscene->scene->update(timestamp, 0.0, 1, true, true, true); + ikscene->scene->update(eval_ctx, timestamp, 0.0, 1, true, true, true); } } // compute constraint error @@ -1744,7 +1744,7 @@ static void execute_scene(Scene *blscene, IK_Scene *ikscene, bItasc *ikparam, fl //--------------------------------------------------- // plugin interface // -void itasc_initialize_tree(struct Scene *scene, Object *ob, float ctime) +void itasc_initialize_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, float ctime) { bPoseChannel *pchan; int count = 0; @@ -1764,13 +1764,13 @@ void itasc_initialize_tree(struct Scene *scene, Object *ob, float ctime) // if at least one tree, create the scenes from the PoseTree stored in the channels // postpone until execute_tree: this way the pose constraint are included if (count) - create_scene(scene, ob, ctime); + create_scene(eval_ctx, scene, ob, ctime); itasc_update_param(ob->pose); // make sure we don't rebuilt until the user changes something important ob->pose->flag &= ~POSE_WAS_REBUILT; } -void itasc_execute_tree(struct Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime) +void itasc_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime) { if (ob->pose->ikdata) { IK_Data *ikdata = (IK_Data *)ob->pose->ikdata; @@ -1787,7 +1787,7 @@ void itasc_execute_tree(struct Scene *scene, Object *ob, bPoseChannel *pchan_ro if (timestep > 0.2f) timestep = 0.2f; } - execute_scene(scene, ikscene, ikparam, ctime, timestep); + execute_scene(eval_ctx, scene, ikscene, ikparam, ctime, timestep); break; } } diff --git a/source/blender/ikplugin/intern/itasc_plugin.h b/source/blender/ikplugin/intern/itasc_plugin.h index bcd95bc31ca..fb948e98696 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.h +++ b/source/blender/ikplugin/intern/itasc_plugin.h @@ -40,8 +40,8 @@ extern "C" { #endif -void itasc_initialize_tree(struct Scene *scene, struct Object *ob, float ctime); -void itasc_execute_tree(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan_root, float ctime); +void itasc_initialize_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime); +void itasc_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan_root, float ctime); void itasc_release_tree(struct Scene *scene, struct Object *ob, float ctime); void itasc_clear_data(struct bPose *pose); void itasc_clear_cache(struct bPose *pose); diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index e7abfdc7d67..f1f36351e79 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -205,6 +205,7 @@ typedef enum IMB_BlendMode { IMB_BLEND_SATURATION = 21, IMB_BLEND_LUMINOSITY = 22, IMB_BLEND_COLOR = 23, + IMB_BLEND_INTERPOLATE = 24, IMB_BLEND_COPY = 1000, IMB_BLEND_COPY_RGB = 1001, diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index ec544e65355..1fa3b943524 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -1104,7 +1104,7 @@ void IMB_exr_write_channels(void *handle) if (data->channels.first) { const size_t num_pixels = ((size_t)data->width) * data->height; - half *rect_half = NULL, *current_rect_half; + half *rect_half = NULL, *current_rect_half = NULL; /* We allocate teporary storage for half pixels for all the channels at once. */ if (data->num_half_channels != 0) { diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c index 3360fd7548e..c4325caac91 100644 --- a/source/blender/imbuf/intern/rectop.c +++ b/source/blender/imbuf/intern/rectop.c @@ -301,8 +301,8 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask, int destx, int desty, int origx, int origy, int srcx, int srcy, int width, int height, IMB_BlendMode mode, bool accumulate) { - unsigned int *drect = NULL, *orect, *srect = NULL, *dr, *or, *sr; - float *drectf = NULL, *orectf, *srectf = NULL, *drf, *orf, *srf; + unsigned int *drect = NULL, *orect = NULL, *srect = NULL, *dr, *or, *sr; + float *drectf = NULL, *orectf = NULL, *srectf = NULL, *drf, *orf, *srf; unsigned short *cmaskrect = curvemask, *cmr; unsigned short *dmaskrect = dmask, *dmr; unsigned short *texmaskrect = texmask, *tmr; @@ -424,6 +424,7 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask, else { switch (mode) { case IMB_BLEND_MIX: + case IMB_BLEND_INTERPOLATE: func = blend_color_mix_byte; func_float = blend_color_mix_float; break; @@ -563,9 +564,15 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask, mask_src[0] = src[0]; mask_src[1] = src[1]; mask_src[2] = src[2]; - mask_src[3] = divide_round_i(src[3] * mask, 65535); - func((unsigned char *)dr, (unsigned char *)or, mask_src); + if (mode == IMB_BLEND_INTERPOLATE) { + mask_src[3] = src[3]; + blend_color_interpolate_byte((unsigned char *)dr, (unsigned char *)or, mask_src, mask / 65535.0f); + } + else { + mask_src[3] = divide_round_i(src[3] * mask, 65535); + func((unsigned char *)dr, (unsigned char *)or, mask_src); + } } } } @@ -588,9 +595,15 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask, mask_src[0] = src[0]; mask_src[1] = src[1]; mask_src[2] = src[2]; - mask_src[3] = divide_round_i(src[3] * mask, 65535); - func((unsigned char *)dr, (unsigned char *)or, mask_src); + if (mode == IMB_BLEND_INTERPOLATE) { + mask_src[3] = src[3]; + blend_color_interpolate_byte((unsigned char *)dr, (unsigned char *)or, mask_src, mask / 65535.0f); + } + else { + mask_src[3] = divide_round_i(src[3] * mask, 65535); + func((unsigned char *)dr, (unsigned char *)or, mask_src); + } } } } @@ -642,12 +655,16 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask, mask = min_ff(mask, 65535.0); if (mask > *dmr) { - float mask_srf[4]; - *dmr = mask; - mul_v4_v4fl(mask_srf, srf, mask / 65535.0f); - func_float(drf, orf, mask_srf); + if (mode == IMB_BLEND_INTERPOLATE) { + blend_color_interpolate_float(drf, orf, srf, mask / 65535.0f); + } + else { + float mask_srf[4]; + mul_v4_v4fl(mask_srf, srf, mask / 65535.0f); + func_float(drf, orf, mask_srf); + } } } } @@ -664,11 +681,15 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask, mask = min_ff(mask, 65535.0); if (srf[3] && (mask > 0.0f)) { - float mask_srf[4]; - - mul_v4_v4fl(mask_srf, srf, mask / 65535.0f); + if (mode == IMB_BLEND_INTERPOLATE) { + blend_color_interpolate_float(drf, orf, srf, mask / 65535.0f); + } + else { + float mask_srf[4]; + mul_v4_v4fl(mask_srf, srf, mask / 65535.0f); + func_float(drf, orf, mask_srf); + } - func_float(drf, orf, mask_srf); } } } diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index ed29f2336de..d457401bb33 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -143,6 +143,7 @@ typedef struct ID { int us; int icon_id; IDProperty *properties; + void *py_instance; } ID; /** @@ -363,6 +364,9 @@ enum { LIB_TAG_ID_RECALC_DATA = 1 << 13, LIB_TAG_ANIM_NO_RECALC = 1 << 14, LIB_TAG_ID_RECALC_ALL = (LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA), + + /* The datablock is a copy-on-write version. */ + LIB_TAG_COPY_ON_WRITE = (1 << 15), }; /* To filter ID types (filter_id) */ @@ -401,7 +405,7 @@ enum { FILTER_ID_PA = (1 << 27), FILTER_ID_CF = (1 << 28), FILTER_ID_WS = (1 << 29), - FILTER_ID_LP = (1 << 31), + FILTER_ID_LP = (1u << 31), }; /* IMPORTANT: this enum matches the order currently use in set_listbasepointers, diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 90d6bbb4f1e..7809d2d1c4a 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -530,7 +530,7 @@ typedef enum eActionGroup_Flag { AGRP_MODIFIERS_OFF = (1 << 7), AGRP_TEMP = (1 << 30), - AGRP_MOVED = (1 << 31) + AGRP_MOVED = (1u << 31) } eActionGroup_Flag; @@ -773,7 +773,7 @@ typedef enum ACHAN_FLAG { ACHAN_EXPANDED = (1 << 4), ACHAN_SHOWIPO = (1 << 5), ACHAN_SHOWCONS = (1 << 6), - ACHAN_MOVED = (1 << 31) + ACHAN_MOVED = (1u << 31) } ACHAN_FLAG; #endif /* __DNA_ACTION_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index e50a2637fff..935a893f689 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -685,7 +685,7 @@ typedef enum eNlaStrip_Flag { /* temporary editing flags */ /* NLA-Strip is really just a temporary meta used to facilitate easier transform code */ NLASTRIP_FLAG_TEMP_META = (1<<30), - NLASTRIP_FLAG_EDIT_TOUCHED = (1<<31) + NLASTRIP_FLAG_EDIT_TOUCHED = (1u << 31) } eNlaStrip_Flag; /* NLA Strip Type */ diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 1df7435c940..298a794500c 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -213,7 +213,7 @@ typedef enum BrushFlags { BRUSH_CUSTOM_ICON = (1 << 28), BRUSH_LINE = (1 << 29), BRUSH_ABSOLUTE_JITTER = (1 << 30), - BRUSH_CURVE = (1 << 31) + BRUSH_CURVE = (1u << 31) } BrushFlags; typedef enum { diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 6d5f7b39cb5..5071859f82e 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -99,7 +99,7 @@ typedef enum ModifierMode { eModifierMode_Expanded = (1 << 4), eModifierMode_Virtual = (1 << 5), eModifierMode_ApplyOnSpline = (1 << 6), - eModifierMode_DisableTemporary = (1 << 31) + eModifierMode_DisableTemporary = (1u << 31) } ModifierMode; typedef struct ModifierData { @@ -1516,7 +1516,7 @@ enum { MOD_DATATRANSFER_USE_VERT = 1 << 28, MOD_DATATRANSFER_USE_EDGE = 1 << 29, MOD_DATATRANSFER_USE_LOOP = 1 << 30, - MOD_DATATRANSFER_USE_POLY = 1 << 31, + MOD_DATATRANSFER_USE_POLY = 1u << 31, }; /* Set Split Normals modifier */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index b922ac072b0..de1214e9b3d 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -214,8 +214,11 @@ typedef struct bNode { * and replacing all uses with per-instance data. */ short preview_xsize, preview_ysize; /* reserved size of the preview rect */ - int pad2; + short pad2[2]; struct uiBlock *block; /* runtime during drawing */ + + float ssr_id; /* XXX: eevee only, id of screen space reflection layer, needs to be a float to feed GPU_uniform. */ + float pad3; } bNode; /* node->flag */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 4eb44531767..d8a11b83fea 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -70,6 +70,8 @@ typedef struct bDeformGroup { typedef struct bFaceMap { struct bFaceMap *next, *prev; char name[64]; /* MAX_VGROUP_NAME */ + char flag; + char pad[7]; } bFaceMap; /* Object Runtime display data */ @@ -297,15 +299,15 @@ typedef struct Object { struct FluidsimSettings *fluidsimSettings; /* if fluidsim enabled, store additional settings */ - /* Runtime valuated curve-specific data, not stored in the file */ - struct CurveCache *curve_cache; - struct DerivedMesh *derivedDeform, *derivedFinal; uint64_t lastDataMask; /* the custom data layer mask that was last used to calculate derivedDeform and derivedFinal */ uint64_t customdata_mask; /* (extra) custom data layer mask to use for creating derivedmesh, set by depsgraph */ unsigned int state; /* bit masks of game controllers that are active */ unsigned int init_state; /* bit masks of initial state as recorded by the users */ + /* Runtime valuated curve-specific data, not stored in the file */ + struct CurveCache *curve_cache; + ListBase gpulamp; /* runtime, for glsl lamp display only */ ListBase pc_ids; ListBase *duplilist; /* for temporary dupli list storage, only for use by RNA API */ diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index f01da3a57fd..54fe5d7da56 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -260,8 +260,9 @@ typedef struct ParticleSettings { /* modified dm support */ short use_modifier_stack; - short pad5[3]; + short pad5; + int recalc; } ParticleSettings; typedef struct ParticleSystem { diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 83747527432..f6dc5741863 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1759,12 +1759,12 @@ typedef struct Scene { /* Physics simulation settings */ struct PhysicsSettings physics_settings; - /* Movie Tracking */ - struct MovieClip *clip; /* active movie clip */ - uint64_t customdata_mask; /* XXX. runtime flag for drawing, actually belongs in the window, only used by BKE_object_handle_update() */ uint64_t customdata_mask_modal; /* XXX. same as above but for temp operator use (gl renders) */ + /* Movie Tracking */ + struct MovieClip *clip; /* active movie clip */ + /* Color Management */ ColorManagedViewSettings view_settings; ColorManagedDisplaySettings display_settings; diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 75ae1cdab95..e3e5aaf8ca4 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -376,7 +376,7 @@ enum { /* uiList filter orderby type */ enum { UILST_FLT_SORT_ALPHA = 1 << 0, - UILST_FLT_SORT_REVERSE = 1 << 31 /* Special value, bitflag used to reverse order! */ + UILST_FLT_SORT_REVERSE = 1u << 31 /* Special value, bitflag used to reverse order! */ }; #define UILST_FLT_SORT_MASK (((unsigned int)UILST_FLT_SORT_REVERSE) - 1) diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 1f4e4df4660..74a1a13c2eb 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -442,7 +442,7 @@ enum { /* access scene strips directly (like a metastrip) */ SEQ_SCENE_STRIPS = (1 << 30), - SEQ_INVALID_EFFECT = (1 << 31), + SEQ_INVALID_EFFECT = (1u << 31), }; /* StripProxy->storage */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 833db376191..68cc5c2d79e 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -744,7 +744,7 @@ typedef enum eFileSel_File_Types { FILE_TYPE_ALEMBIC = (1 << 16), FILE_TYPE_DIR = (1 << 30), /* An FS directory (i.e. S_ISDIR on its path is true). */ - FILE_TYPE_BLENDERLIB = (1 << 31), + FILE_TYPE_BLENDERLIB = (1u << 31), } eFileSel_File_Types; /* Selection Flags in filesel: struct direntry, unsigned char selflag */ diff --git a/source/blender/makesdna/DNA_text_types.h b/source/blender/makesdna/DNA_text_types.h index 8d1bba6ca4f..c7969cd30e7 100644 --- a/source/blender/makesdna/DNA_text_types.h +++ b/source/blender/makesdna/DNA_text_types.h @@ -61,8 +61,8 @@ typedef struct Text { char *undo_buf; int undo_pos, undo_len; - void *compiled; double mtime; + void *compiled; } Text; #define TXT_TABSIZE 4 diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 01ad818d0f1..742bdba6fad 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -48,7 +48,8 @@ struct ColorBand; #define MAX_STYLE_NAME 64 -/* default uifont_id offered by Blender */ +/* default offered by Blender. + * uiFont.uifont_id */ typedef enum eUIFont_ID { UIFONT_DEFAULT = 0, /* UIFONT_BITMAP = 1 */ /* UNUSED */ @@ -64,7 +65,7 @@ typedef struct uiFont { struct uiFont *next, *prev; char filename[1024];/* 1024 = FILE_MAX */ short blf_id; /* from blfont lib */ - short uifont_id; /* own id */ + short uifont_id; /* own id (eUIFont_ID) */ short r_to_l; /* fonts that read from left to right */ short hinting; } uiFont; @@ -84,7 +85,7 @@ typedef struct uiFontStyle { float shadowcolor; /* 1 value, typically white or black anyway */ } uiFontStyle; -/* uiFontStyle->align */ +/* uiFontStyle.align */ typedef enum eFontStyle_Align { UI_STYLE_TEXT_LEFT = 0, UI_STYLE_TEXT_CENTER = 1, @@ -354,11 +355,11 @@ typedef struct ThemeWireColor { char select[4]; char active[4]; - short flag; + short flag; /* eWireColor_Flags */ short pad; } ThemeWireColor; -/* flags for ThemeWireColor */ +/* ThemeWireColor.flag */ typedef enum eWireColor_Flags { TH_WIRECOLOR_CONSTCOLS = (1 << 0), TH_WIRECOLOR_TEXTCOLS = (1 << 1), @@ -434,7 +435,8 @@ typedef struct UserDef { /* UserDef has separate do-version handling, and can be read from other files */ int versionfile, subversionfile; - int flag, dupflag; + int flag; /* eUserPref_Flag */ + int dupflag; /* eDupli_ID_Flags */ int savetime; char tempdir[768]; /* FILE_MAXDIR length */ char fontdir[768]; @@ -450,14 +452,15 @@ typedef struct UserDef { int anim_player_preset; short v2d_min_gridsize; /* minimum spacing between gridlines in View2D grids */ - short timecode_style; /* style of timecode display */ + short timecode_style; /* eTimecodeStyles, style of timecode display */ short versions; short dbl_click_time; short gameflags; short wheellinescroll; - int uiflag, uiflag2; + int uiflag; /* eUserpref_UI_Flag */ + int uiflag2; /* eUserpref_UI_Flag2 */ int language; short userpref, viewzoom; @@ -473,7 +476,7 @@ typedef struct UserDef { int pad1; char node_margin; /* node insert offset (aka auto-offset) margin, but might be useful for later stuff as well */ char pad2; - short transopts; + short transopts; /* eUserpref_Translation_Flags */ short menuthreshold1, menuthreshold2; /* startup template */ @@ -491,13 +494,13 @@ typedef struct UserDef { short undosteps; short undomemory; short gp_manhattendist, gp_euclideandist, gp_eraser; - short gp_settings; + short gp_settings; /* eGP_UserdefSettings */ short tb_leftmouse, tb_rightmouse; struct SolidLight light[3]; short manipulator_flag, manipulator_size; int pad3; short textimeout, texcollectrate; - short wmdrawmethod; /* removed wmpad */ + short wmdrawmethod; /* eWM_DrawMethod */ short dragthreshold; int memcachelimit; int prefetchframes; @@ -510,13 +513,13 @@ typedef struct UserDef { short smooth_viewtx; /* miliseconds to spend spinning the view */ short glreslimit; short curssize; - short color_picker_type; + short color_picker_type; /* eColorPicker_Types */ char ipo_new; /* interpolation mode for newly added F-Curves */ char keyhandles_new; /* handle types for newly added keyframes */ char gpu_select_method; char gpu_select_pick_deph; char pad4; - char view_frame_type; + char view_frame_type; /* eZoomFrame_Mode */ int view_frame_keyframes; /* number of keyframes to zoom around current frame */ float view_frame_seconds; /* seconds to zoom around current frame */ @@ -531,15 +534,16 @@ typedef struct UserDef { float ndof_sensitivity; /* overall sensitivity of 3D mouse */ float ndof_orbit_sensitivity; float ndof_deadzone; /* deadzone of 3D mouse */ - int ndof_flag; /* flags for 3D mouse */ + int ndof_flag; /* eNdof_Flag, flags for 3D mouse */ - short ogl_multisamples; /* amount of samples for OpenGL FSA, if zero no FSA */ + short ogl_multisamples; /* eMultiSample_Type, amount of samples for OpenGL FSA, if zero no FSA */ - short image_draw_method; /* Method to be used to draw the images (AUTO, GLSL, Textures or DrawPixels) */ + /* eImageDrawMethod, Method to be used to draw the images (AUTO, GLSL, Textures or DrawPixels) */ + short image_draw_method; float glalphaclip; - short autokey_mode; /* autokeying mode */ + short autokey_mode; /* eAutokey_Mode, autokeying mode */ short autokey_flag; /* flags for autokeying */ short text_render, pad9; /* options for text rendering */ @@ -583,7 +587,7 @@ extern UserDef U; /* from blenkernel blender.c */ /* ***************** USERDEF ****************** */ -/* userpref/section */ +/* UserDef.userpref (UI active_section) */ typedef enum eUserPref_Section { USER_SECTION_INTERFACE = 0, USER_SECTION_EDIT = 1, @@ -594,19 +598,19 @@ typedef enum eUserPref_Section { USER_SECTION_ADDONS = 6, } eUserPref_Section; -/* flag */ +/* UserDef.flag */ typedef enum eUserPref_Flag { USER_AUTOSAVE = (1 << 0), -/* USER_AUTOGRABGRID = (1 << 1), deprecated */ -/* USER_AUTOROTGRID = (1 << 2), deprecated */ -/* USER_AUTOSIZEGRID = (1 << 3), deprecated */ + USER_FLAG_DEPRECATED_1 = (1 << 1), /* cleared */ + USER_FLAG_DEPRECATED_2 = (1 << 2), /* cleared */ + USER_FLAG_DEPRECATED_3 = (1 << 3), /* cleared */ /* USER_SCENEGLOBAL = (1 << 4), deprecated */ USER_TRACKBALL = (1 << 5), -/* USER_DUPLILINK = (1 << 6), deprecated */ -/* USER_FSCOLLUM = (1 << 7), deprecated */ + USER_FLAG_DEPRECATED_6 = (1 << 6), /* cleared */ + USER_FLAG_DEPRECATED_7 = (1 << 7), /* cleared */ USER_MAT_ON_OB = (1 << 8), -/* USER_NO_CAPSLOCK = (1 << 9), */ /* not used anywhere */ -/* USER_VIEWMOVE = (1 << 10), */ /* not used anywhere */ + USER_FLAG_DEPRECATED_9 = (1 << 9), /* cleared */ + USER_FLAG_DEPRECATED_10 = (1 << 10), /* cleared */ USER_TOOLTIPS = (1 << 11), USER_TWOBUTTONMOUSE = (1 << 12), USER_NONUMPAD = (1 << 13), @@ -625,7 +629,7 @@ typedef enum eUserPref_Flag { USER_TOOLTIPS_PYTHON = (1 << 26), } eUserPref_Flag; -/* flag */ +/* bPathCompare.flag */ typedef enum ePathCompare_Flag { USER_PATHCMP_GLOB = (1 << 0), } ePathCompare_Flag; @@ -636,33 +640,34 @@ typedef enum ePathCompare_Flag { cfra = 0; \ } (void)0 -/* viewzoom */ +/* UserDef.viewzoom */ typedef enum eViewZoom_Style { USER_ZOOM_CONT = 0, USER_ZOOM_SCALE = 1, USER_ZOOM_DOLLY = 2 } eViewZoom_Style; -/* navigation_mode */ +/* UserDef.navigation_mode */ typedef enum eViewNavigation_Method { VIEW_NAVIGATION_WALK = 0, VIEW_NAVIGATION_FLY = 1, } eViewNavigation_Method; -/* flag */ +/* UserDef.flag */ typedef enum eWalkNavigation_Flag { USER_WALK_GRAVITY = (1 << 0), USER_WALK_MOUSE_REVERSE = (1 << 1), } eWalkNavigation_Flag; -/* uiflag */ +/* UserDef.uiflag */ typedef enum eUserpref_UI_Flag { /* flags 0 and 1 were old flags (for autokeying) that aren't used anymore */ USER_WHEELZOOMDIR = (1 << 2), USER_FILTERFILEEXTS = (1 << 3), USER_DRAWVIEWINFO = (1 << 4), USER_PLAINMENUS = (1 << 5), - /* flags 6 and 7 were old flags that are no-longer used */ + USER_LOCK_CURSOR_ADJUST = (1 << 6), + USER_UIFLAG_DEPRECATED_7 = (1 << 7), /* cleared */ USER_ALLWINCODECS = (1 << 8), USER_MENUOPENAUTO = (1 << 9), USER_ZBUF_CURSOR = (1 << 10), @@ -686,17 +691,18 @@ typedef enum eUserpref_UI_Flag { USER_HIDE_RECENT = (1 << 28), USER_SHOW_THUMBNAILS = (1 << 29), USER_QUIT_PROMPT = (1 << 30), - USER_HIDE_SYSTEM_BOOKMARKS = (1 << 31) + USER_HIDE_SYSTEM_BOOKMARKS = (1u << 31) } eUserpref_UI_Flag; -/* uiflag2 */ +/* UserDef.uiflag2 */ typedef enum eUserpref_UI_Flag2 { USER_KEEP_SESSION = (1 << 0), USER_REGION_OVERLAP = (1 << 1), USER_TRACKPAD_NATURAL = (1 << 2), } eUserpref_UI_Flag2; -/* Auto-Keying mode */ +/* Auto-Keying mode. + * UserDef.autokey_mode */ typedef enum eAutokey_Mode { /* AUTOKEY_ON is a bitflag */ AUTOKEY_ON = 1, @@ -706,7 +712,8 @@ typedef enum eAutokey_Mode { AUTOKEY_MODE_EDITKEYS = 5 } eAutokey_Mode; -/* Zoom to frame mode */ +/* Zoom to frame mode. + * UserDef.view_frame_type */ typedef enum eZoomFrame_Mode { ZOOM_FRAME_MODE_KEEP_RANGE = 0, ZOOM_FRAME_MODE_SECONDS = 1, @@ -729,20 +736,20 @@ typedef enum eAutokey_Flag { ANIMRECORD_FLAG_WITHNLA = (1 << 10), } eAutokey_Flag; -/* transopts */ +/* UserDef.transopts */ typedef enum eUserpref_Translation_Flags { USER_TR_TOOLTIPS = (1 << 0), USER_TR_IFACE = (1 << 1), -/* USER_TR_MENUS = (1 << 2), deprecated */ -/* USER_TR_FILESELECT = (1 << 3), deprecated */ -/* USER_TR_TEXTEDIT = (1 << 4), deprecated */ + USER_TR_DEPRECATED_2 = (1 << 2), /* cleared */ + USER_TR_DEPRECATED_3 = (1 << 3), /* cleared */ + USER_TR_DEPRECATED_4 = (1 << 4), /* cleared */ USER_DOTRANSLATE = (1 << 5), - USER_USETEXTUREFONT = (1 << 6), -/* CONVERT_TO_UTF8 = (1 << 7), deprecated */ + USER_TR_DEPRECATED_6 = (1 << 6), /* cleared */ + USER_TR_DEPRECATED_7 = (1 << 7), /* cleared */ USER_TR_NEWDATANAME = (1 << 8), } eUserpref_Translation_Flags; -/* dupflag */ +/* UserDef.dupflag */ typedef enum eDupli_ID_Flags { USER_DUP_MESH = (1 << 0), USER_DUP_CURVE = (1 << 1), @@ -758,14 +765,13 @@ typedef enum eDupli_ID_Flags { USER_DUP_PSYS = (1 << 11) } eDupli_ID_Flags; -/* gameflags */ +/* UserDef.gameflags */ typedef enum eOpenGL_RenderingOptions { - /* USER_DEPRECATED_FLAG = (1 << 0), */ - /* USER_DISABLE_SOUND = (1 << 1), */ /* deprecated, don't use without checking for */ - /* backwards compatibilty in do_versions! */ - USER_DISABLE_MIPMAP = (1 << 2), - /* USER_DISABLE_VBO = (1 << 3), */ /* DEPRECATED we always use vertex buffers now */ - /* USER_DISABLE_AA = (1 << 4), */ /* DEPRECATED */ + USER_GL_RENDER_DEPRECATED_0 = (1 << 0), + USER_GL_RENDER_DEPRECATED_1 = (1 << 1), + USER_DISABLE_MIPMAP = (1 << 2), + USER_GL_RENDER_DEPRECATED_3 = (1 << 3), + USER_GL_RENDER_DEPRECATED_4 = (1 << 4), } eOpenGL_RenderingOptions; /* selection method for opengl gpu_select_method */ @@ -775,7 +781,8 @@ typedef enum eOpenGL_SelectOptions { USER_SELECT_USE_SELECT_RENDERMODE = 2 } eOpenGL_SelectOptions; -/* wm draw method */ +/* wm draw method. + * UserDef.wmdrawmethod */ typedef enum eWM_DrawMethod { USER_DRAW_TRIPLE = 0, USER_DRAW_OVERLAP = 1, @@ -784,12 +791,16 @@ typedef enum eWM_DrawMethod { USER_DRAW_OVERLAP_FLIP = 4, } eWM_DrawMethod; -/* text draw options */ +/* text draw options + * UserDef.text_render */ typedef enum eText_Draw_Options { USER_TEXT_DISABLE_AA = (1 << 0), } eText_Draw_Options; -/* gp_settings (Grease Pencil Settings) */ +/* tw_flag (transform widget) */ + +/* Grease Pencil Settings. + * UserDef.gp_settings */ typedef enum eGP_UserdefSettings { GP_PAINT_DOSMOOTH = (1 << 0), GP_PAINT_DOSIMPLIFY = (1 << 1), @@ -800,7 +811,8 @@ enum { USER_MANIPULATOR_SHADED = (1 << 1), }; -/* color picker types */ +/* Color Picker Types. + * UserDef.color_picker_type */ typedef enum eColorPicker_Types { USER_CP_CIRCLE_HSV = 0, USER_CP_SQUARE_SV = 1, @@ -809,7 +821,8 @@ typedef enum eColorPicker_Types { USER_CP_CIRCLE_HSL = 4, } eColorPicker_Types; -/* timecode display styles */ +/* timecode display styles + * UserDef.timecode_style */ typedef enum eTimecodeStyles { /* as little info as is necessary to show relevant info * with '+' to denote the frames @@ -844,7 +857,7 @@ typedef enum eTheme_DrawTypes { TH_SHADED = 4 } eTheme_DrawTypes; -/* ndof_flag (3D mouse options) */ +/* UserDef.ndof_flag (3D mouse options) */ typedef enum eNdof_Flag { NDOF_SHOW_GUIDE = (1 << 0), NDOF_FLY_HELICOPTER = (1 << 1), @@ -877,6 +890,7 @@ typedef enum eNdof_Flag { #define NDOF_PIXELS_PER_SECOND 600.0f +/* UserDef.ogl_multisamples */ typedef enum eMultiSample_Type { USER_MULTISAMPLE_NONE = 0, USER_MULTISAMPLE_2 = 2, @@ -884,7 +898,8 @@ typedef enum eMultiSample_Type { USER_MULTISAMPLE_8 = 8, USER_MULTISAMPLE_16 = 16, } eMultiSample_Type; - + +/* UserDef.image_draw_method */ typedef enum eImageDrawMethod { /* IMAGE_DRAW_METHOD_AUTO = 0, */ /* Currently unused */ IMAGE_DRAW_METHOD_GLSL = 1, @@ -892,6 +907,7 @@ typedef enum eImageDrawMethod { IMAGE_DRAW_METHOD_DRAWPIXELS = 3, } eImageDrawMethod; +/* UserDef.virtual_pixel */ typedef enum eUserpref_VirtualPixel { VIRTUAL_PIXEL_NATIVE = 0, VIRTUAL_PIXEL_DOUBLE = 1, diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index dd5e7ffe06f..c7342719f86 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -116,6 +116,8 @@ extern EnumPropertyItem rna_enum_brush_image_tool_items[]; extern EnumPropertyItem rna_enum_gpencil_sculpt_brush_items[]; +extern EnumPropertyItem rna_enum_uv_sculpt_tool_items[]; + extern EnumPropertyItem rna_enum_axis_xy_items[]; extern EnumPropertyItem rna_enum_axis_xyz_items[]; diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index 99ef0f9c8c4..2dac9f67b7a 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -178,7 +178,7 @@ typedef enum PropertyFlag { * after every typed char, instead of waiting final validation. Used e.g. for text searchbox. * It will also cause UI_BUT_VALUE_CLEAR to be set for text buttons. We could add an own flag * for search/filter properties, but this works just fine for now. */ - PROP_TEXTEDIT_UPDATE = (1 << 31), + PROP_TEXTEDIT_UPDATE = (1u << 31), /* icon */ PROP_ICONS_CONSECUTIVE = (1 << 12), diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 01831c95b7a..985192c6b35 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -146,6 +146,9 @@ set(GENSRC_CFLAGS) if(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang")) set(GENSRC_CFLAGS "-Wno-missing-prototypes") endif() +if(CMAKE_C_COMPILER_ID MATCHES "Clang") + set(GENSRC_CFLAGS "${GENSRC_CFLAGS} -Wno-missing-variable-declarations") +endif() if(GENSRC_CFLAGS) set_source_files_properties(${GENSRC} PROPERTIES COMPILE_FLAGS "${GENSRC_CFLAGS}") diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 3d162137bd1..1c6172ef667 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -394,6 +394,14 @@ static void rna_ID_animation_data_free(ID *id, Main *bmain) DEG_relations_tag_update(bmain); } +#ifdef WITH_PYTHON +void **rna_ID_instance(PointerRNA *ptr) +{ + ID *id = (ID *)ptr->data; + return &id->py_instance; +} +#endif + static void rna_IDPArray_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { IDProperty *prop = (IDProperty *)ptr->data; @@ -1071,6 +1079,10 @@ static void rna_def_ID(BlenderRNA *brna) "Tag the ID to update its display data, " "e.g. when calling :class:`bpy.types.Scene.update`"); RNA_def_enum_flag(func, "refresh", update_flag_items, 0, "", "Type of updates to perform"); + +#ifdef WITH_PYTHON + RNA_def_struct_register_funcs(srna, NULL, NULL, "rna_ID_instance"); +#endif } static void rna_def_library(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c index 36078cb0864..5b7a023aab1 100644 --- a/source/blender/makesrna/intern/rna_context.c +++ b/source/blender/makesrna/intern/rna_context.c @@ -101,6 +101,14 @@ static PointerRNA rna_Context_region_data_get(PointerRNA *ptr) return PointerRNA_NULL; } +static PointerRNA rna_Context_manipulator_group_get(PointerRNA *ptr) +{ + bContext *C = (bContext *)ptr->data; + PointerRNA newptr; + RNA_pointer_create(NULL, &RNA_ManipulatorGroup, CTX_wm_manipulator_group(C), &newptr); + return newptr; +} + static PointerRNA rna_Context_main_get(PointerRNA *ptr) { bContext *C = (bContext *)ptr->data; @@ -230,6 +238,11 @@ void RNA_def_context(BlenderRNA *brna) RNA_def_property_struct_type(prop, "RegionView3D"); RNA_def_property_pointer_funcs(prop, "rna_Context_region_data_get", NULL, NULL, NULL); + prop = RNA_def_property(srna, "manipulator_group", PROP_POINTER, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "ManipulatorGroup"); + RNA_def_property_pointer_funcs(prop, "rna_Context_manipulator_group_get", NULL, NULL, NULL); + /* Data */ prop = RNA_def_property(srna, "blend_data", PROP_POINTER, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c index 9ea12e3befa..6043224df5d 100644 --- a/source/blender/makesrna/intern/rna_depsgraph.c +++ b/source/blender/makesrna/intern/rna_depsgraph.c @@ -131,9 +131,14 @@ static void rna_Depsgraph_debug_graphviz(Depsgraph *graph, const char *filename) fclose(f); } -static void rna_Depsgraph_debug_rebuild(Depsgraph *UNUSED(graph), Main *bmain) +static void rna_Depsgraph_debug_rebuild(Depsgraph *UNUSED(graph), bContext *C) { + Main *bmain = CTX_data_main(C); + EvaluationContext eval_ctx; Scene *sce; + + CTX_data_eval_ctx(C, &eval_ctx); + DEG_relations_tag_update(bmain); for (sce = bmain->scene.first; sce; sce = sce->id.next) { DEG_scene_relations_rebuild(bmain, sce); @@ -307,7 +312,7 @@ static void rna_def_depsgraph(BlenderRNA *brna) RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); func = RNA_def_function(srna, "debug_rebuild", "rna_Depsgraph_debug_rebuild"); - RNA_def_function_flag(func, FUNC_USE_MAIN); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); func = RNA_def_function(srna, "debug_stats", "rna_Depsgraph_debug_stats"); RNA_def_function_ui_description(func, "Report the number of elements in the Dependency Graph"); diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index b657d2fab00..98a5febd746 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -42,6 +42,7 @@ struct Mesh; struct Object; struct ReportList; struct SDNA; +struct SceneLayer; /* Data structures used during define */ @@ -222,6 +223,7 @@ void rna_ID_name_set(struct PointerRNA *ptr, const char *value); struct StructRNA *rna_ID_refine(struct PointerRNA *ptr); struct IDProperty *rna_ID_idprops(struct PointerRNA *ptr, bool create); void rna_ID_fake_user_set(struct PointerRNA *ptr, int value); +void **rna_ID_instance(PointerRNA *ptr); struct IDProperty *rna_PropertyGroup_idprops(struct PointerRNA *ptr, bool create); void rna_PropertyGroup_unregister(struct Main *bmain, struct StructRNA *type); struct StructRNA *rna_PropertyGroup_register(struct Main *bmain, struct ReportList *reports, void *data, @@ -411,7 +413,7 @@ 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 Main *bmain, struct ReportList *reports, struct Scene *sce, struct SceneLayer *sl, struct Object *ob, int apply_modifiers, int settings, int calc_tessface, int calc_undeformed); /* XXX, these should not need to be defined here~! */ diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 5b898d7fd40..d980916aeec 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -299,9 +299,15 @@ 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, + Main *bmain, ReportList *reports, Scene *sce, SceneLayer *sl, Object *ob, int apply_modifiers, int settings, int calc_tessface, int calc_undeformed) { + EvaluationContext eval_ctx; + + DEG_evaluation_context_init(&eval_ctx, settings); + eval_ctx.ctime = (float)sce->r.cfra + sce->r.subframe; + eval_ctx.scene_layer = sl; + switch (ob->type) { case OB_FONT: case OB_CURVE: @@ -314,7 +320,7 @@ Mesh *rna_Main_meshes_new_from_object( return NULL; } - return BKE_mesh_new_from_object(bmain, sce, ob, apply_modifiers, settings, calc_tessface, calc_undeformed); + return BKE_mesh_new_from_object(&eval_ctx, bmain, sce, ob, apply_modifiers, settings, calc_tessface, calc_undeformed); } static Lamp *rna_Main_lamps_new(Main *bmain, const char *name, int type) @@ -879,6 +885,8 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop) 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, "scene_layer", "SceneLayer", "", "Scene layer within which 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"); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 3accd2f23f1..8ff5474ed91 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -46,6 +46,7 @@ #include "RNA_access.h" #include "RNA_define.h" #include "RNA_types.h" +#include "RNA_enum_types.h" #include "rna_internal.h" @@ -186,12 +187,10 @@ static void rna_MeshEdgeLayer_name_set(PointerRNA *ptr, const char *value) rna_cd_layer_name_set(rna_mesh_edata(ptr), (CustomDataLayer *)ptr->data, value); } #endif -#if 0 static void rna_MeshPolyLayer_name_set(PointerRNA *ptr, const char *value) { rna_cd_layer_name_set(rna_mesh_pdata(ptr), (CustomDataLayer *)ptr->data, value); } -#endif static void rna_MeshLoopLayer_name_set(PointerRNA *ptr, const char *value) { rna_cd_layer_name_set(rna_mesh_ldata(ptr), (CustomDataLayer *)ptr->data, value); @@ -1176,6 +1175,75 @@ static int rna_MeshPaintMaskLayer_data_length(PointerRNA *ptr) /* End paint mask */ +/* Face maps */ + +DEFINE_CUSTOMDATA_LAYER_COLLECTION(face_map, pdata, CD_FACEMAP) +DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(face_map, pdata, CD_FACEMAP, active, MeshFaceMapLayer) + +static char *rna_MeshFaceMapLayer_path(PointerRNA *ptr) +{ + CustomDataLayer *cdl = ptr->data; + char name_esc[sizeof(cdl->name) * 2]; + BLI_strescape(name_esc, cdl->name, sizeof(name_esc)); + return BLI_sprintfN("face_maps[\"%s\"]", name_esc); +} + +static void rna_MeshFaceMapLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Mesh *me = rna_mesh(ptr); + CustomDataLayer *layer = (CustomDataLayer *)ptr->data; + rna_iterator_array_begin(iter, layer->data, sizeof(int), me->totpoly, 0, NULL); +} + +static int rna_MeshFaceMapLayer_data_length(PointerRNA *ptr) +{ + Mesh *me = rna_mesh(ptr); + return me->totpoly; +} + +static PointerRNA rna_Mesh_face_map_new(struct Mesh *me, ReportList *reports, const char *name) +{ + if (BKE_mesh_ensure_facemap_customdata(me) == false) { + BKE_report(reports, RPT_ERROR, "Currently only single face-map layers are supported"); + return PointerRNA_NULL; + } + + CustomData *pdata = rna_mesh_pdata_helper(me); + + int index = CustomData_get_layer_index(pdata, CD_FACEMAP); + BLI_assert(index != -1); + CustomDataLayer *cdl = &pdata->layers[index]; + rna_cd_layer_name_set(pdata, cdl, name); + + PointerRNA ptr; + RNA_pointer_create(&me->id, &RNA_MeshFaceMapLayer, cdl, &ptr); + return ptr; +} + +static void rna_Mesh_face_map_remove(struct Mesh *me, ReportList *reports, struct CustomDataLayer *layer) +{ + /* just for sanity check */ + { + CustomData *pdata = rna_mesh_pdata_helper(me); + int index = CustomData_get_layer_index(pdata, CD_FACEMAP); + if (index != -1) { + CustomDataLayer *layer_test = &pdata->layers[index]; + if (layer != layer_test) { + /* don't show name, its likely freed memory */ + BKE_report(reports, RPT_ERROR, "FaceMap not in mesh"); + return; + } + } + } + + if (BKE_mesh_clear_facemap_customdata(me) == false) { + BKE_reportf(reports, RPT_ERROR, "Error removing face-map"); + } +} + +/* End face maps */ + + static int rna_MeshTessFace_verts_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]) { MFace *face = (MFace *)ptr->data; @@ -1608,6 +1676,12 @@ void rna_MeshStringProperty_s_set(PointerRNA *ptr, const char *value) MStringProperty *ms = (MStringProperty *)ptr->data; BLI_strncpy(ms->s, value, sizeof(ms->s)); } + +static char *rna_MeshFaceMap_path(PointerRNA *ptr) +{ + return rna_PolyCustomData_data_path(ptr, "face_maps", CD_FACEMAP); +} + /***************************************/ static int rna_Mesh_tot_vert_get(PointerRNA *ptr) @@ -1796,6 +1870,10 @@ static void UNUSED_FUNCTION(rna_mesh_unused)(void) (void)rna_Mesh_vertex_color_render_index_get; (void)rna_Mesh_vertex_color_render_index_set; (void)rna_Mesh_vertex_color_render_set; + (void)rna_Mesh_face_map_index_range; + (void)rna_Mesh_face_map_active_index_set; + (void)rna_Mesh_face_map_active_index_get; + (void)rna_Mesh_face_map_active_set; /* end unused function block */ } @@ -3091,6 +3169,79 @@ static void rna_def_paint_mask(BlenderRNA *brna, PropertyRNA *UNUSED(cprop)) RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); } +static void rna_def_face_map(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "MeshFaceMapLayer", NULL); + RNA_def_struct_ui_text(srna, "Mesh Face Map Layer", "Per-face map index"); + RNA_def_struct_sdna(srna, "CustomDataLayer"); + RNA_def_struct_path_func(srna, "rna_MeshFaceMapLayer_path"); + + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_struct_name_property(srna, prop); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshPolyLayer_name_set"); + RNA_def_property_ui_text(prop, "Name", "Name of face-map layer"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + + prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "MeshFaceMap"); + RNA_def_property_ui_text(prop, "Data", ""); + RNA_def_property_collection_funcs(prop, "rna_MeshFaceMapLayer_data_begin", "rna_iterator_array_next", + "rna_iterator_array_end", "rna_iterator_array_get", + "rna_MeshFaceMapLayer_data_length", NULL, NULL, NULL); + + /* FaceMap struct */ + srna = RNA_def_struct(brna, "MeshFaceMap", NULL); + RNA_def_struct_sdna(srna, "MIntProperty"); + RNA_def_struct_ui_text(srna, "Int Property", ""); + RNA_def_struct_path_func(srna, "rna_MeshFaceMap_path"); + + prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "i"); + RNA_def_property_ui_text(prop, "Value", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); +} + +static void rna_def_face_maps(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + PropertyRNA *prop; + + RNA_def_property_srna(cprop, "MeshFaceMapLayers"); + srna = RNA_def_struct(brna, "MeshFaceMapLayers", NULL); + RNA_def_struct_ui_text(srna, "Mesh Face Map Layer", "Per-face map index"); + RNA_def_struct_sdna(srna, "Mesh"); + RNA_def_struct_ui_text(srna, "Mesh FaceMaps", "Collection of mesh face-maps"); + + /* add this since we only ever have one layer anyway, don't bother with active_index */ + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MeshFaceMapLayer"); + RNA_def_property_pointer_funcs(prop, "rna_Mesh_face_map_active_get", + NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Active FaceMap Layer", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + + FunctionRNA *func; + PropertyRNA *parm; + + func = RNA_def_function(srna, "new", "rna_Mesh_face_map_new"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Add a float property layer to Mesh"); + RNA_def_string(func, "name", "Face Map", 0, "", "Face map name"); + parm = RNA_def_pointer(func, "layer", "MeshFaceMapLayer", "", "The newly created layer"); + RNA_def_parameter_flags(parm, 0, PARM_RNAPTR); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_Mesh_face_map_remove"); + RNA_def_function_ui_description(func, "Remove a face map layer"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "layer", "MeshFaceMapLayer", "", "The layer to remove"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); +} + static void rna_def_mesh(BlenderRNA *brna) { StructRNA *srna; @@ -3250,6 +3401,15 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_text(prop, "String Property Layers", ""); rna_def_polygon_string_layers(brna, prop); + /* face-maps */ + prop = RNA_def_property(srna, "face_maps", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer"); + RNA_def_property_collection_funcs(prop, "rna_Mesh_face_maps_begin", NULL, NULL, NULL, + "rna_Mesh_face_maps_length", NULL, NULL, NULL); + RNA_def_property_struct_type(prop, "MeshFaceMapLayer"); + RNA_def_property_ui_text(prop, "FaceMap", ""); + rna_def_face_maps(brna, prop); + /* Skin vertices */ prop = RNA_def_property(srna, "skin_vertices", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "vdata.layers", "vdata.totlayer"); @@ -3523,6 +3683,7 @@ void RNA_def_mesh(BlenderRNA *brna) rna_def_mcol(brna); rna_def_mloopcol(brna); rna_def_mproperties(brna); + rna_def_face_map(brna); } #endif diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 5ecfc495cd4..9ea4bed5857 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -66,6 +66,8 @@ #include "NOD_composite.h" +#include "DEG_depsgraph.h" + EnumPropertyItem rna_enum_node_socket_in_out_items[] = { { SOCK_IN, "IN", 0, "Input", "" }, { SOCK_OUT, "OUT", 0, "Output", "" }, @@ -240,10 +242,10 @@ bNodeTreeType *rna_node_tree_type_from_enum(int value) EnumPropertyItem *rna_node_tree_type_itemf(void *data, int (*poll)(void *data, bNodeTreeType *), bool *r_free) { - EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem tmp = {0}; EnumPropertyItem *item = NULL; int totitem = 0, i = 0; - + NODE_TREE_TYPES_BEGIN (nt) { if (poll && !poll(data, nt)) { @@ -263,9 +265,14 @@ EnumPropertyItem *rna_node_tree_type_itemf(void *data, int (*poll)(void *data, b } NODE_TREE_TYPES_END; + if (totitem == 0) { + *r_free = false; + return DummyRNA_NULL_items; + } + RNA_enum_item_end(&item, &totitem); *r_free = true; - + return item; } @@ -312,9 +319,9 @@ bNodeType *rna_node_type_from_enum(int value) EnumPropertyItem *rna_node_type_itemf(void *data, int (*poll)(void *data, bNodeType *), bool *r_free) { EnumPropertyItem *item = NULL; - EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem tmp = {0}; int totitem = 0, i = 0; - + NODE_TYPES_BEGIN(ntype) if (poll && !poll(data, ntype)) { ++i; @@ -331,9 +338,15 @@ EnumPropertyItem *rna_node_type_itemf(void *data, int (*poll)(void *data, bNodeT ++i; NODE_TYPES_END + + if (totitem == 0) { + *r_free = false; + return DummyRNA_NULL_items; + } + RNA_enum_item_end(&item, &totitem); *r_free = true; - + return item; } @@ -380,10 +393,10 @@ bNodeSocketType *rna_node_socket_type_from_enum(int value) EnumPropertyItem *rna_node_socket_type_itemf(void *data, int (*poll)(void *data, bNodeSocketType *), bool *r_free) { EnumPropertyItem *item = NULL; - EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem tmp = {0}; int totitem = 0, i = 0; StructRNA *srna; - + NODE_SOCKET_TYPES_BEGIN(stype) if (poll && !poll(data, stype)) { ++i; @@ -401,9 +414,15 @@ EnumPropertyItem *rna_node_socket_type_itemf(void *data, int (*poll)(void *data, ++i; NODE_SOCKET_TYPES_END + + if (totitem == 0) { + *r_free = false; + return DummyRNA_NULL_items; + } + RNA_enum_item_end(&item, &totitem); *r_free = true; - + return item; } @@ -412,25 +431,25 @@ static EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C), Pointer EnumPropertyItem *item = NULL; EnumPropertyItem tmp; int totitem = 0; - + /* hack, don't want to add include path to RNA just for this, since in the future RNA types * for nodes should be defined locally at runtime anyway ... */ - + tmp.value = NODE_CUSTOM; tmp.identifier = "CUSTOM"; tmp.name = "Custom"; tmp.description = "Custom Node"; tmp.icon = ICON_NONE; RNA_enum_item_add(&item, &totitem, &tmp); - + tmp.value = NODE_UNDEFINED; tmp.identifier = "UNDEFINED"; tmp.name = "UNDEFINED"; tmp.description = ""; tmp.icon = ICON_NONE; RNA_enum_item_add(&item, &totitem, &tmp); - + #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \ if (STREQ(#Category, "Node")) { \ tmp.value = ID; \ @@ -442,7 +461,7 @@ static EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C), Pointer } #include "../../nodes/NOD_static_types.h" #undef DefNode - + if (RNA_struct_is_a(ptr->type, &RNA_ShaderNode)) { #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \ if (STREQ(#Category, "ShaderNode")) { \ @@ -470,7 +489,7 @@ static EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C), Pointer #include "../../nodes/NOD_static_types.h" #undef DefNode } - + if (RNA_struct_is_a(ptr->type, &RNA_TextureNode)) { #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \ if (STREQ(#Category, "TextureNode")) { \ @@ -487,7 +506,7 @@ static EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C), Pointer RNA_enum_item_end(&item, &totitem); *r_free = true; - + return item; } @@ -2277,30 +2296,10 @@ static void rna_NodeSocketStandard_vector_range(PointerRNA *ptr, float *min, flo static void rna_NodeSocket_value_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - /* XXX: TODO (sergey/dalai) move this to depsgraph. */ bNodeTree *ntree = (bNodeTree *)ptr->id.data; if (ntree->type == NTREE_SHADER) { - FOREACH_NODETREE(bmain, tntree, id) { - if (GS(id->name) == ID_WO) { - World *wo = (World *)id; - if ((BLI_listbase_is_empty(&wo->gpumaterial) == false) && - ntreeHasTree(tntree, ntree)) - { - wo->update_flag = 1; - GPU_material_uniform_buffer_tag_dirty(&wo->gpumaterial); - WM_main_add_notifier(NC_MATERIAL | ND_SHADING, NULL); - } - } - else if (GS(id->name) == ID_MA) { - Material *ma = (Material *)id; - if ((BLI_listbase_is_empty(&ma->gpumaterial) == false) && - ntreeHasTree(tntree, ntree)) - { - GPU_material_uniform_buffer_tag_dirty(&ma->gpumaterial); - WM_main_add_notifier(NC_MATERIAL | ND_SHADING, ma); - } - } - } FOREACH_NODETREE_END + DEG_id_tag_update_ex(bmain, ptr->id.data, DEG_TAG_SHADING_UPDATE); + WM_main_add_notifier(NC_MATERIAL | ND_SHADING, NULL); } else { rna_NodeSocket_update(bmain, scene, ptr); @@ -2651,9 +2650,9 @@ static void rna_Node_image_layer_update(Main *bmain, Scene *scene, PointerRNA *p static EnumPropertyItem *renderresult_layers_add_enum(RenderLayer *rl) { EnumPropertyItem *item = NULL; - EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem tmp = {0}; int i = 0, totitem = 0; - + while (rl) { tmp.identifier = rl->name; /* little trick: using space char instead empty string makes the item selectable in the dropdown */ @@ -2665,7 +2664,7 @@ static EnumPropertyItem *renderresult_layers_add_enum(RenderLayer *rl) RNA_enum_item_add(&item, &totitem, &tmp); rl = rl->next; } - + RNA_enum_item_end(&item, &totitem); return item; @@ -2678,18 +2677,17 @@ static EnumPropertyItem *rna_Node_image_layer_itemf(bContext *UNUSED(C), Pointer Image *ima = (Image *)node->id; EnumPropertyItem *item = NULL; RenderLayer *rl; - - if (ima && ima->rr) { - rl = ima->rr->layers.first; - item = renderresult_layers_add_enum(rl); - } - else { - int totitem = 0; - RNA_enum_item_end(&item, &totitem); + + if (ima == NULL || ima->rr == NULL) { + *r_free = false; + return DummyRNA_NULL_items; } - + + rl = ima->rr->layers.first; + item = renderresult_layers_add_enum(rl); + *r_free = true; - + return item; } @@ -2740,19 +2738,22 @@ static EnumPropertyItem *renderresult_views_add_enum(RenderView *rv) } static EnumPropertyItem *rna_Node_image_view_itemf(bContext *UNUSED(C), PointerRNA *ptr, - PropertyRNA *UNUSED(prop), bool *free) + PropertyRNA *UNUSED(prop), bool *r_free) { bNode *node = (bNode *)ptr->data; Image *ima = (Image *)node->id; EnumPropertyItem *item = NULL; RenderView *rv; - if (!ima || !(ima->rr)) return NULL; + if (ima == NULL || ima->rr == NULL) { + *r_free = false; + return DummyRNA_NULL_items; + } rv = ima->rr->views.first; item = renderresult_views_add_enum(rv); - *free = true; + *r_free = true; return item; } @@ -2764,18 +2765,17 @@ static EnumPropertyItem *rna_Node_scene_layer_itemf(bContext *UNUSED(C), Pointer Scene *sce = (Scene *)node->id; EnumPropertyItem *item = NULL; RenderLayer *rl; - - if (sce) { - rl = sce->r.layers.first; - item = renderresult_layers_add_enum(rl); - } - else { - int totitem = 0; - RNA_enum_item_end(&item, &totitem); + + if (sce == NULL) { + *r_free = false; + return DummyRNA_NULL_items; } - + + rl = sce->r.layers.first; + item = renderresult_layers_add_enum(rl); + *r_free = true; - + return item; } @@ -2792,7 +2792,7 @@ static EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), PointerRNA { bNode *node = (bNode *)ptr->data; EnumPropertyItem *item = NULL; - EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem tmp = {0}; int totitem = 0; switch (node->custom1) { @@ -2829,7 +2829,7 @@ static EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), PointerRNA RNA_enum_item_add(&item, &totitem, &tmp); break; default: - break; + return DummyRNA_NULL_items; } RNA_enum_item_end(&item, &totitem); @@ -3120,6 +3120,7 @@ static int point_density_vertex_color_source_from_shader(NodeShaderTexPointDensi void rna_ShaderNodePointDensity_density_cache(bNode *self, Scene *scene, + SceneLayer *sl, int settings) { NodeShaderTexPointDensity *shader_point_density = self->storage; @@ -3157,12 +3158,13 @@ void rna_ShaderNodePointDensity_density_cache(bNode *self, /* Single-threaded sampling of the voxel domain. */ RE_point_density_cache(scene, - pd, + sl, pd, settings == 1); } void rna_ShaderNodePointDensity_density_calc(bNode *self, Scene *scene, + SceneLayer *sl, int settings, int *length, float **values) @@ -3184,7 +3186,7 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self, } /* Single-threaded sampling of the voxel domain. */ - RE_point_density_sample(scene, pd, + RE_point_density_sample(scene, sl, pd, resolution, settings == 1, *values); @@ -3197,6 +3199,7 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self, void rna_ShaderNodePointDensity_density_minmax(bNode *self, Scene *scene, + SceneLayer *sl, int settings, float r_min[3], float r_max[3]) @@ -3208,7 +3211,7 @@ void rna_ShaderNodePointDensity_density_minmax(bNode *self, zero_v3(r_max); return; } - RE_point_density_minmax(scene, pd, settings == 1, r_min, r_max); + RE_point_density_minmax(scene, sl, pd, settings == 1, r_min, r_max); } #else @@ -3373,7 +3376,7 @@ static void def_frame(StructRNA *srna) prop = RNA_def_property(srna, "text", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_struct_type(prop, "Text"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Text", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); @@ -3643,7 +3646,7 @@ static void def_sh_lamp(StructRNA *srna) prop = RNA_def_property(srna, "lamp_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_struct_type(prop, "Object"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Lamp_object_poll"); RNA_def_property_ui_text(prop, "Lamp Object", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); @@ -4017,7 +4020,7 @@ static void def_sh_tex_coord(StructRNA *srna) 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"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Object", "Use coordinates from this object (for object texture coordinates output)"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); @@ -4133,7 +4136,7 @@ static void def_sh_tex_pointdensity(StructRNA *srna) 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"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Object", "Object to take point data from"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); @@ -4192,11 +4195,13 @@ 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, "scene", "Scene", "", ""); + RNA_def_pointer(func, "sl", "SceneLayer", "", ""); 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, "scene", "Scene", "", ""); + RNA_def_pointer(func, "sl", "SceneLayer", "", ""); 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); @@ -4206,6 +4211,7 @@ 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, "scene", "Scene", "", ""); + RNA_def_pointer(func, "sl", "SceneLayer", "", ""); 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); @@ -4830,7 +4836,7 @@ static void def_cmp_render_layers(StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_scene_set", NULL, NULL); RNA_def_property_struct_type(prop, "Scene"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Scene", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_scene_layer_update"); @@ -5487,7 +5493,7 @@ static void def_cmp_defocus(StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_scene_set", NULL, NULL); RNA_def_property_struct_type(prop, "Scene"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Scene", "Scene from which to select the active camera (render scene if undefined)"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 513e25cbd15..3fc877ca357 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -859,9 +859,14 @@ static void rna_Object_active_particle_system_index_set(PointerRNA *ptr, int val static void rna_Object_particle_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) { + /* TODO: Disabled for now, because bContext is not available. */ +#if 0 Object *ob = (Object *)ptr->id.data; - - PE_current_changed(scene, ob); + PE_current_changed(NULL, scene, ob); +#else + (void) scene; + (void) ptr; +#endif } /* rotation - axis-angle */ @@ -1774,6 +1779,11 @@ static void rna_def_face_map(BlenderRNA *brna) /* update data because modifiers may use [#24761] */ RNA_def_property_update(prop, NC_GEOM | ND_DATA | NA_RENAME, "rna_Object_internal_update_data"); + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT); + RNA_def_property_ui_text(prop, "Select", "Face-map selection state (for tools to use)"); + /* important not to use a notifier here, creates a feedback loop! */ + prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_int_funcs(prop, "rna_FaceMap_index_get", NULL, NULL); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 1e2d4d6ab18..7bf483ad2f0 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -197,14 +197,16 @@ 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, ReportList *reports, Scene *sce, + Object *ob, bContext *C, ReportList *reports, Scene *sce, SceneLayer *sl, int apply_modifiers, int settings, int calc_tessface, int calc_undeformed) { - return rna_Main_meshes_new_from_object(G.main, reports, sce, ob, apply_modifiers, settings, calc_tessface, calc_undeformed); + Main *bmain = CTX_data_main(C); + + return rna_Main_meshes_new_from_object(bmain, reports, sce, sl, ob, apply_modifiers, settings, calc_tessface, calc_undeformed); } /* mostly a copy from convertblender.c */ -static void dupli_render_particle_set(Scene *scene, Object *ob, int level, int enable) +static void dupli_render_particle_set(EvaluationContext *eval_ctx, Scene *scene, Object *ob, 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 */ @@ -233,7 +235,7 @@ static void dupli_render_particle_set(Scene *scene, Object *ob, int level, int e /* 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(scene, ob, CD_MASK_BAREMESH | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL); + dm = mesh_create_derived_render(eval_ctx, scene, ob, CD_MASK_BAREMESH | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL); dm->release(dm); for (psys = ob->particlesystem.first; psys; psys = psys->next) @@ -245,14 +247,17 @@ static void dupli_render_particle_set(Scene *scene, Object *ob, int level, int e group = ob->dup_group; for (go = group->gobject.first; go; go = go->next) - dupli_render_particle_set(scene, go->ob, level + 1, enable); + dupli_render_particle_set(eval_ctx, scene, go->ob, level + 1, enable); } /* When no longer needed, duplilist should be freed with Object.free_duplilist */ -static void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce, int settings) +static void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *reports, Scene *sce, int settings) { bool for_render = (settings == DAG_EVAL_RENDER); EvaluationContext eval_ctx; - DEG_evaluation_context_init(&eval_ctx, settings); + + CTX_data_eval_ctx(C, &eval_ctx); + + eval_ctx.mode = settings; if (!(ob->transflag & OB_DUPLI)) { BKE_report(reports, RPT_ERROR, "Object does not have duplis"); @@ -267,10 +272,10 @@ static void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene * ob->duplilist = NULL; } if (for_render) - dupli_render_particle_set(sce, ob, 0, 1); + dupli_render_particle_set(&eval_ctx, sce, ob, 0, 1); ob->duplilist = object_duplilist(&eval_ctx, sce, ob); if (for_render) - dupli_render_particle_set(sce, ob, 0, 0); + dupli_render_particle_set(&eval_ctx, sce, ob, 0, 0); /* ob->duplilist should now be freed with Object.free_duplilist */ } @@ -644,9 +649,11 @@ void RNA_api_object(StructRNA *srna) /* mesh */ 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); + 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, "scene_layer", "SceneLayer", "", "Scene layer within which 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"); @@ -665,7 +672,7 @@ void RNA_api_object(StructRNA *srna) parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene within which to evaluate duplis"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); RNA_def_enum(func, "settings", dupli_eval_mode_items, 0, "", "Generate texture coordinates for rendering"); - RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_CONTEXT); func = RNA_def_function(srna, "dupli_list_clear", "rna_Object_free_duplilist"); RNA_def_function_ui_description(func, "Free the list of dupli objects"); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 0f2eb9412e7..93801a508c5 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -614,8 +614,14 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, R } } -static void rna_ParticleSystem_set_resolution(ParticleSystem *particlesystem, Scene *scene, Object *object, int resolution) +static void rna_ParticleSystem_set_resolution(ParticleSystem *particlesystem, Scene *scene, SceneLayer *sl, 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.scene_layer = sl; + if (resolution == eModifierMode_Render) { ParticleSystemModifierData *psmd = psys_get_modifier(object, particlesystem); float mat[4][4]; @@ -624,7 +630,7 @@ static void rna_ParticleSystem_set_resolution(ParticleSystem *particlesystem, Sc psys_render_set(object, particlesystem, mat, mat, 1, 1, 0.f); psmd->flag &= ~eParticleSystemFlag_psys_updated; - particle_system_update(scene, object, particlesystem, true); + particle_system_update(&eval_ctx, scene, object, particlesystem, true); } else { ParticleSystemModifierData *psmd = psys_get_modifier(object, particlesystem); @@ -634,7 +640,7 @@ static void rna_ParticleSystem_set_resolution(ParticleSystem *particlesystem, Sc } psmd->flag &= ~eParticleSystemFlag_psys_updated; - particle_system_update(scene, object, particlesystem, false); + particle_system_update(&eval_ctx, scene, object, particlesystem, false); } } @@ -3547,6 +3553,7 @@ static void rna_def_particle_system(BlenderRNA *brna) 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, "scene_layer", "SceneLayer", "", "SceneLayer"); RNA_def_pointer(func, "object", "Object", "", "Object"); RNA_def_enum(func, "resolution", resolution_items, 0, "", "Resolution settings to apply"); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index d8ed9800b4c..d9e7d3f6a84 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -673,7 +673,7 @@ static void rna_PoseChannel_matrix_set(PointerRNA *ptr, const float *values) Object *ob = (Object *)ptr->id.data; float tmat[4][4]; - BKE_armature_mat_pose_to_bone_ex(ob, pchan, (float (*)[4])values, tmat); + BKE_armature_mat_pose_to_bone_ex(NULL, ob, pchan, (float (*)[4])values, tmat); BKE_pchan_apply_mat4(pchan, tmat, false); /* no compat for predictable result */ } diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 267a81c81af..19002d1229b 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -385,6 +385,16 @@ static PointerRNA rna_RenderEngine_render_get(PointerRNA *ptr) } } +static PointerRNA rna_RenderEngine_scene_layer_get(PointerRNA *ptr) +{ + RenderEngine *engine = (RenderEngine *)ptr->data; + if (engine->re != NULL) { + SceneLayer* scene_layer = RE_engine_get_scene_layer(engine->re); + return rna_pointer_inherit_refine(ptr, &RNA_SceneLayer, scene_layer); + } + return rna_pointer_inherit_refine(ptr, &RNA_SceneLayer, NULL); +} + static PointerRNA rna_RenderEngine_camera_override_get(PointerRNA *ptr) { RenderEngine *engine = (RenderEngine *)ptr->data; @@ -729,6 +739,11 @@ static void rna_def_render_engine(BlenderRNA *brna) prop = RNA_def_enum(func, "type", render_pass_type_items, SOCK_FLOAT, "Type", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + prop = RNA_def_property(srna, "scene_layer", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "SceneLayer"); + RNA_def_property_pointer_funcs(prop, "rna_RenderEngine_scene_layer_get", NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Scene layer", ""); + /* registration */ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 7b0174bfb5d..7587f4fe2a1 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -99,13 +99,15 @@ EnumPropertyItem rna_enum_exr_codec_items[] = { }; #endif -EnumPropertyItem uv_sculpt_relaxation_items[] = { +#ifndef RNA_RUNTIME +static EnumPropertyItem uv_sculpt_relaxation_items[] = { {UV_SCULPT_TOOL_RELAX_LAPLACIAN, "LAPLACIAN", 0, "Laplacian", "Use Laplacian method for relaxation"}, {UV_SCULPT_TOOL_RELAX_HC, "HC", 0, "HC", "Use HC method for relaxation"}, {0, NULL, 0, NULL, NULL} }; +#endif -EnumPropertyItem uv_sculpt_tool_items[] = { +EnumPropertyItem rna_enum_uv_sculpt_tool_items[] = { {UV_SCULPT_TOOL_PINCH, "PINCH", 0, "Pinch", "Pinch UVs"}, {UV_SCULPT_TOOL_RELAX, "RELAX", 0, "Relax", "Relax UVs"}, {UV_SCULPT_TOOL_GRAB, "GRAB", 0, "Grab", "Grab UVs"}, @@ -180,11 +182,13 @@ EnumPropertyItem rna_enum_snap_node_element_items[] = { {0, NULL, 0, NULL, NULL} }; -EnumPropertyItem snap_uv_element_items[] = { +#ifndef RNA_RUNTIME +static EnumPropertyItem snap_uv_element_items[] = { {SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_SNAP_INCREMENT, "Increment", "Snap to increments of grid"}, {SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"}, {0, NULL, 0, NULL, NULL} }; +#endif EnumPropertyItem rna_enum_curve_fit_method_items[] = { {CURVE_PAINT_FIT_METHOD_REFIT, "REFIT", 0, "Refit", "Incrementally re-fit the curve (high quality)"}, @@ -270,12 +274,14 @@ EnumPropertyItem rna_enum_curve_fit_method_items[] = { R_IMF_ENUM_TIFF \ -EnumPropertyItem image_only_type_items[] = { +#ifdef RNA_RUNTIME +static EnumPropertyItem image_only_type_items[] = { IMAGE_TYPE_ITEMS_IMAGE_ONLY {0, NULL, 0, NULL, NULL} }; +#endif EnumPropertyItem rna_enum_image_type_items[] = { {0, "", 0, N_("Image"), NULL}, @@ -413,7 +419,8 @@ EnumPropertyItem rna_enum_bake_pass_filter_type_items[] = { {0, NULL, 0, NULL, NULL} }; -EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = { +#ifndef RNA_RUNTIME +static EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = { /* interpolation */ {0, "", 0, N_("Interpolation"), "Standard transitions between keyframes"}, {GP_IPO_LINEAR, "LINEAR", ICON_IPO_LINEAR, "Linear", "Straight-line interpolation between A and B (i.e. no ease in/out)"}, @@ -437,6 +444,8 @@ EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = { {0, NULL, 0, NULL, NULL} }; +#endif + EnumPropertyItem rna_enum_layer_collection_mode_settings_type_items[] = { {COLLECTION_MODE_OBJECT, "OBJECT", 0, "Object", ""}, {COLLECTION_MODE_EDIT, "EDIT", 0, "Edit", ""}, @@ -1569,9 +1578,12 @@ static void rna_RenderSettings_engine_set(PointerRNA *ptr, int value) { RenderData *rd = (RenderData *)ptr->data; RenderEngineType *type = BLI_findlink(&R_engines, value); + Scene *scene = (Scene *)ptr->id.data; if (type) BLI_strncpy_utf8(rd->engine, type->idname, sizeof(rd->engine)); + + DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE); } static EnumPropertyItem *rna_RenderSettings_engine_itemf( @@ -2622,6 +2634,14 @@ RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(volumetric_light_clamp) RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(volumetric_shadows) RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(volumetric_shadow_samples) RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(volumetric_colored_transmittance) +RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_enable) +RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_halfres) +RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(ssr_ray_count) +RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_quality) +RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_max_roughness) +RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_thickness) +RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_border_fade) +RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(ssr_firefly_fac) /* object engine */ RNA_LAYER_MODE_OBJECT_GET_SET_BOOL(show_wire) @@ -3554,7 +3574,7 @@ static void rna_def_tool_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "uv_sculpt_tool", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "uv_sculpt_tool"); - RNA_def_property_enum_items(prop, uv_sculpt_tool_items); + RNA_def_property_enum_items(prop, rna_enum_uv_sculpt_tool_items); RNA_def_property_ui_text(prop, "UV Sculpt Tools", "Select Tools for the UV sculpt brushes"); prop = RNA_def_property(srna, "uv_relax_method", PROP_ENUM, PROP_NONE); @@ -6180,6 +6200,70 @@ static void rna_def_scene_layer_engine_settings_eevee(BlenderRNA *brna) /* see RNA_LAYER_ENGINE_GET_SET macro */ + /* Screen Space Reflection */ + prop = RNA_def_property(srna, "ssr_enable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_enable_get", + "rna_LayerEngineSettings_Eevee_ssr_enable_set"); + RNA_def_property_ui_text(prop, "Screen Space Reflections", "Enable screen space reflection"); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update"); + + prop = RNA_def_property(srna, "ssr_halfres", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_halfres_get", + "rna_LayerEngineSettings_Eevee_ssr_halfres_set"); + RNA_def_property_ui_text(prop, "Half Res Trace", "Raytrace at a lower resolution"); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update"); + + prop = RNA_def_property(srna, "ssr_quality", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_quality_get", + "rna_LayerEngineSettings_Eevee_ssr_quality_set", NULL); + RNA_def_property_ui_text(prop, "Trace Quality", "Quality of the screen space raytracing"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update"); + + prop = RNA_def_property(srna, "ssr_max_roughness", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_max_roughness_get", + "rna_LayerEngineSettings_Eevee_ssr_max_roughness_set", NULL); + RNA_def_property_ui_text(prop, "Max Roughness", "Do not raytrace reflections for roughness above this value"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update"); + + prop = RNA_def_property(srna, "ssr_ray_count", PROP_INT, PROP_NONE); + RNA_def_property_int_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_ray_count_get", + "rna_LayerEngineSettings_Eevee_ssr_ray_count_set", NULL); + RNA_def_property_ui_text(prop, "Samples", "Number of rays to trace per pixels"); + RNA_def_property_range(prop, 1, 4); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update"); + + prop = RNA_def_property(srna, "ssr_thickness", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_thickness_get", + "rna_LayerEngineSettings_Eevee_ssr_thickness_set", NULL); + RNA_def_property_ui_text(prop, "Thickness", "Pixel thickness used to detect intersection"); + RNA_def_property_range(prop, 1e-6f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 5, 3); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update"); + + prop = RNA_def_property(srna, "ssr_border_fade", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_border_fade_get", + "rna_LayerEngineSettings_Eevee_ssr_border_fade_set", NULL); + RNA_def_property_ui_text(prop, "Edge Fading", "Screen percentage used to fade the SSR"); + RNA_def_property_range(prop, 0.0f, 0.5f); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update"); + + prop = RNA_def_property(srna, "ssr_firefly_fac", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_firefly_fac_get", + "rna_LayerEngineSettings_Eevee_ssr_firefly_fac_set", NULL); + RNA_def_property_ui_text(prop, "Clamp", "Clamp pixel intensity to remove noise (0 to disabled)"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update"); + /* Volumetrics */ prop = RNA_def_property(srna, "volumetric_enable", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_enable_get", diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 2ebd0eb2f11..ff870ec40b7 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -151,7 +151,7 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, int previe } static void rna_Scene_ray_cast( - Scene *scene, SceneLayer *sl, float origin[3], float direction[3], float ray_dist, + Scene *scene, bContext *C, SceneLayer *sl, float origin[3], float direction[3], float ray_dist, int *r_success, float r_location[3], float r_normal[3], int *r_index, Object **r_ob, float r_obmat[16]) { @@ -161,7 +161,7 @@ static void rna_Scene_ray_cast( G.main, scene, sl, 0); bool ret = ED_transform_snap_object_project_ray_ex( - sctx, + C, sctx, &(const struct SnapObjectParams){ .snap_select = SNAP_ALL, }, @@ -289,7 +289,12 @@ static void rna_Scene_collada_export( int limit_precision, int keep_bind_info) { - collada_export(scene, + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); + + collada_export(&eval_ctx, + scene, CTX_data_scene_layer(C), filepath, @@ -347,6 +352,7 @@ void RNA_api_scene(StructRNA *srna) /* Ray Cast */ func = RNA_def_function(srna, "ray_cast", "rna_Scene_ray_cast"); RNA_def_function_ui_description(func, "Cast a ray onto in object space"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); parm = RNA_def_pointer(func, "scene_layer", "SceneLayer", "", "Scene Layer"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); /* ray start and end */ diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index b72e88cd79f..5090c06ad21 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -28,6 +28,7 @@ #include <stdlib.h> #include "RNA_define.h" +#include "RNA_enum_types.h" #include "rna_internal.h" @@ -75,13 +76,15 @@ EnumPropertyItem rna_enum_gpencil_sculpt_brush_items[] = { { 0, NULL, 0, NULL, NULL } }; -EnumPropertyItem rna_enum_gpencil_lockaxis_items[] = { +#ifndef RNA_RUNTIME +static EnumPropertyItem rna_enum_gpencil_lockaxis_items[] = { { GP_LOCKAXIS_NONE, "GP_LOCKAXIS_NONE", 0, "None", "" }, { GP_LOCKAXIS_X, "GP_LOCKAXIS_X", 0, "X", "Project strokes to plane locked to X" }, { GP_LOCKAXIS_Y, "GP_LOCKAXIS_Y", 0, "Y", "Project strokes to plane locked to Y" }, { GP_LOCKAXIS_Z, "GP_LOCKAXIS_Z", 0, "Z", "Project strokes to plane locked to Z" }, { 0, NULL, 0, NULL, NULL } }; +#endif EnumPropertyItem rna_enum_symmetrize_direction_items[] = { {BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""}, diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index c8cceb54f9b..a43baffeb26 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -4654,7 +4654,7 @@ static void rna_def_space_clip(BlenderRNA *brna) /* path length */ prop = RNA_def_property(srna, "path_length", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "path_length"); - RNA_def_property_range(prop, 0, 50); + RNA_def_property_range(prop, 0, INT_MAX); RNA_def_property_ui_text(prop, "Path Length", "Length of displaying path, in frames"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); diff --git a/source/blender/makesrna/intern/rna_space_api.c b/source/blender/makesrna/intern/rna_space_api.c index aabe421b872..822f5cbb4b6 100644 --- a/source/blender/makesrna/intern/rna_space_api.c +++ b/source/blender/makesrna/intern/rna_space_api.c @@ -36,20 +36,23 @@ #include "ED_screen.h" #include "ED_text.h" -static void rna_RegionView3D_update(ID *id, RegionView3D *rv3d) +static void rna_RegionView3D_update(ID *id, RegionView3D *rv3d, bContext *C) { bScreen *sc = (bScreen *)id; + EvaluationContext eval_ctx; ScrArea *sa; ARegion *ar; + CTX_data_eval_ctx(C, &eval_ctx); + area_region_from_regiondata(sc, rv3d, &sa, &ar); if (sa && ar && sa->spacetype == SPACE_VIEW3D) { View3D *v3d = sa->spacedata.first; Scene *scene = ED_screen_scene_find(sc, G.main->wm.first); - ED_view3d_update_viewmat(scene, v3d, ar, NULL, NULL, NULL); + ED_view3d_update_viewmat(&eval_ctx, scene, v3d, ar, NULL, NULL, NULL); } } @@ -73,7 +76,7 @@ void RNA_api_region_view3d(StructRNA *srna) FunctionRNA *func; func = RNA_def_function(srna, "update", "rna_RegionView3D_update"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_CONTEXT); RNA_def_function_ui_description(func, "Recalculate the view matrices"); } diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index af77d037b69..0a4e69934b7 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -3443,6 +3443,11 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Cursor Depth", "Use the depth under the mouse when placing the cursor"); + prop = RNA_def_property(srna, "use_cursor_lock_adjust", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_LOCK_CURSOR_ADJUST); + RNA_def_property_ui_text(prop, "Cursor Lock Adjust", + "Place the cursor without 'jumping' to the new location (when lock-to-cursor is used)"); + prop = RNA_def_property(srna, "use_camera_lock_parent", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_CAM_LOCK_NO_PARENT); RNA_def_property_ui_text(prop, "Camera Parent Lock", @@ -3919,12 +3924,18 @@ static void rna_def_userdef_system(BlenderRNA *brna) prop = RNA_def_property(srna, "dpi", PROP_INT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display"); + RNA_def_property_ui_text(prop, "DPI", + "DPI for add-ons to use when drawing custom user interface elements, controlled by " + "operating system settings and Blender UI scale, with a reference value of 72 DPI " + "(note that since this value includes a user defined scale, it is not always the " + "actual monitor DPI)"); prop = RNA_def_property(srna, "pixel_size", PROP_FLOAT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_float_sdna(prop, NULL, "pixelsize"); - RNA_def_property_ui_text(prop, "Pixel Size", ""); + RNA_def_property_ui_text(prop, "Pixel Size", + "Suggested line thickness and point size in pixels, for add-ons drawing custom user " + "interface elements, controlled by operating system settings and Blender UI scale"); prop = RNA_def_property(srna, "font_path_ui", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "font_path_ui"); @@ -3972,11 +3983,6 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Translate New Names", "Translate new data names (when adding/creating some)"); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "use_textured_fonts", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_USETEXTUREFONT); - RNA_def_property_ui_text(prop, "Textured Fonts", "Use textures for drawing international fonts"); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - /* System & OpenGL */ prop = RNA_def_property(srna, "solid_lights", PROP_COLLECTION, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_wm_manipulator.c b/source/blender/makesrna/intern/rna_wm_manipulator.c index 030f1a1628c..9334d7da159 100644 --- a/source/blender/makesrna/intern/rna_wm_manipulator.c +++ b/source/blender/makesrna/intern/rna_wm_manipulator.c @@ -136,20 +136,22 @@ static int rna_manipulator_test_select_cb( } static void rna_manipulator_modal_cb( - struct bContext *C, struct wmManipulator *mpr, const struct wmEvent *event, int tweak) + struct bContext *C, struct wmManipulator *mpr, const struct wmEvent *event, + eWM_ManipulatorTweak tweak_flag) { extern FunctionRNA rna_Manipulator_modal_func; wmManipulatorGroup *mgroup = mpr->parent_mgroup; PointerRNA mpr_ptr; ParameterList list; FunctionRNA *func; + const int tweak_flag_int = tweak_flag; RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr); /* RNA_struct_find_function(&mpr_ptr, "modal"); */ func = &rna_Manipulator_modal_func; RNA_parameter_list_create(&list, &mpr_ptr, func); RNA_parameter_set_lookup(&list, "context", &C); RNA_parameter_set_lookup(&list, "event", &event); - RNA_parameter_set_lookup(&list, "tweak", &tweak); + RNA_parameter_set_lookup(&list, "tweak", &tweak_flag_int); mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list); RNA_parameter_list_free(&list); } @@ -210,21 +212,19 @@ static void rna_manipulator_exit_cb( RNA_parameter_list_free(&list); } -static void rna_manipulator_select_cb( - struct bContext *C, struct wmManipulator *mpr, int action) +static void rna_manipulator_select_refresh_cb( + struct wmManipulator *mpr) { - extern FunctionRNA rna_Manipulator_select_func; + extern FunctionRNA rna_Manipulator_select_refresh_func; wmManipulatorGroup *mgroup = mpr->parent_mgroup; PointerRNA mpr_ptr; ParameterList list; FunctionRNA *func; RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr); - /* RNA_struct_find_function(&mpr_ptr, "select"); */ - func = &rna_Manipulator_select_func; + /* RNA_struct_find_function(&mpr_ptr, "select_refresh"); */ + func = &rna_Manipulator_select_refresh_func; RNA_parameter_list_create(&list, &mpr_ptr, func); - RNA_parameter_set_lookup(&list, "context", &C); - RNA_parameter_set_lookup(&list, "action", &action); - mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list); + mgroup->type->ext.call((bContext *)NULL, &mpr_ptr, func, &list); RNA_parameter_list_free(&list); } @@ -309,6 +309,17 @@ static void rna_Manipulator_##func_id##_set(PointerRNA *ptr, float value) \ wmManipulator *mpr = ptr->data; \ mpr->member_id = value; \ } +#define RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_INDEX_RW_DEF(func_id, member_id, index) \ +static float rna_Manipulator_##func_id##_get(PointerRNA *ptr) \ +{ \ + wmManipulator *mpr = ptr->data; \ + return mpr->member_id[index]; \ +} \ +static void rna_Manipulator_##func_id##_set(PointerRNA *ptr, float value) \ +{ \ + wmManipulator *mpr = ptr->data; \ + mpr->member_id[index] = value; \ +} /* wmManipulator.float[len] */ #define RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(func_id, member_id, len) \ static void rna_Manipulator_##func_id##_get(PointerRNA *ptr, float value[len]) \ @@ -342,9 +353,13 @@ static int rna_Manipulator_##func_id##_get(PointerRNA *ptr) \ return (mpr->member_id & flag_value) != 0; \ } -RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(color, color, 4); -RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(color_hi, color_hi, 4); +RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(color, color, 3); +RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(color_hi, color_hi, 3); + +RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_INDEX_RW_DEF(alpha, color, 3); +RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_INDEX_RW_DEF(alpha_hi, color_hi, 3); +RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(matrix_space, matrix_space, 16); RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(matrix_basis, matrix_basis, 16); RNA_MANIPULATOR_GENERIC_FLOAT_ARRAY_RW_DEF(matrix_offset, matrix_offset, 16); @@ -352,31 +367,26 @@ RNA_MANIPULATOR_GENERIC_FLOAT_RW_DEF(scale_basis, scale_basis); RNA_MANIPULATOR_GENERIC_FLOAT_RW_DEF(line_width, line_width); RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_hover, flag, WM_MANIPULATOR_DRAW_HOVER); -RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_active, flag, WM_MANIPULATOR_DRAW_ACTIVE); +RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_modal, flag, WM_MANIPULATOR_DRAW_MODAL); RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_value, flag, WM_MANIPULATOR_DRAW_VALUE); RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_hide, flag, WM_MANIPULATOR_HIDDEN); /* wmManipulator.state */ RNA_MANIPULATOR_FLAG_RO_DEF(state_is_highlight, state, WM_MANIPULATOR_STATE_HIGHLIGHT); -RNA_MANIPULATOR_FLAG_RO_DEF(state_is_active, state, WM_MANIPULATOR_STATE_ACTIVE); +RNA_MANIPULATOR_FLAG_RO_DEF(state_is_modal, state, WM_MANIPULATOR_STATE_MODAL); RNA_MANIPULATOR_FLAG_RO_DEF(state_select, state, WM_MANIPULATOR_STATE_SELECT); -static void rna_Manipulator_name_get(PointerRNA *ptr, char *value) -{ - wmManipulator *mpr = ptr->data; - strcpy(value, mpr->name); -} - -static void rna_Manipulator_name_set(PointerRNA *ptr, const char *value) +static void rna_Manipulator_state_select_set(struct PointerRNA *ptr, int value) { wmManipulator *mpr = ptr->data; - WM_manipulator_name_set(mpr->parent_mgroup, mpr, value); + wmManipulatorGroup *mgroup = mpr->parent_mgroup; + WM_manipulator_select_set(mgroup->parent_mmap, mpr, value); } -static int rna_Manipulator_name_length(PointerRNA *ptr) +static PointerRNA rna_Manipulator_group_get(PointerRNA *ptr) { wmManipulator *mpr = ptr->data; - return strlen(mpr->name); + return rna_pointer_inherit_refine(ptr, &RNA_ManipulatorGroup, mpr->parent_mgroup); } #ifdef WITH_PYTHON @@ -444,7 +454,7 @@ static StructRNA *rna_Manipulator_register( dummywt.setup = (have_function[i++]) ? rna_manipulator_setup_cb : NULL; dummywt.invoke = (have_function[i++]) ? rna_manipulator_invoke_cb : NULL; dummywt.exit = (have_function[i++]) ? rna_manipulator_exit_cb : NULL; - dummywt.select = (have_function[i++]) ? rna_manipulator_select_cb : NULL; + dummywt.select_refresh = (have_function[i++]) ? rna_manipulator_select_refresh_cb : NULL; BLI_assert(i == ARRAY_SIZE(have_function)); } @@ -462,12 +472,10 @@ static StructRNA *rna_Manipulator_register( return dummywt.ext.srna; } -static void rna_Manipulator_unregister(struct Main *UNUSED(bmain), StructRNA *type) +static void rna_Manipulator_unregister(struct Main *bmain, StructRNA *type) { wmManipulatorType *wt = RNA_struct_blender_type_get(type); - /* TODO, remove widgets from interface! */ - if (!wt) return; @@ -475,7 +483,7 @@ static void rna_Manipulator_unregister(struct Main *UNUSED(bmain), StructRNA *ty RNA_struct_free_extension(type, &wt->ext); - WM_manipulatortype_remove_ptr(wt); + WM_manipulatortype_remove_ptr(NULL, bmain, wt); RNA_struct_free(&BLENDER_RNA, type); } @@ -501,28 +509,28 @@ static StructRNA *rna_Manipulator_refine(PointerRNA *mnp_ptr) * \{ */ static wmManipulator *rna_ManipulatorGroup_manipulator_new( - wmManipulatorGroup *mgroup, ReportList *reports, const char *idname, const char *name) + wmManipulatorGroup *mgroup, ReportList *reports, const char *idname) { const wmManipulatorType *wt = WM_manipulatortype_find(idname, true); if (wt == NULL) { BKE_reportf(reports, RPT_ERROR, "ManipulatorType '%s' not known", idname); return NULL; } - wmManipulator *mpr = WM_manipulator_new_ptr(wt, mgroup, name, NULL); + wmManipulator *mpr = WM_manipulator_new_ptr(wt, mgroup, NULL); return mpr; } static void rna_ManipulatorGroup_manipulator_remove( wmManipulatorGroup *mgroup, bContext *C, wmManipulator *mpr) { - WM_manipulator_free(&mgroup->manipulators, mgroup->parent_mmap, mpr, C); + WM_manipulator_unlink(&mgroup->manipulators, mgroup->parent_mmap, mpr, C); } static void rna_ManipulatorGroup_manipulator_clear( wmManipulatorGroup *mgroup, bContext *C) { while (mgroup->manipulators.first) { - WM_manipulator_free(&mgroup->manipulators, mgroup->parent_mmap, mgroup->manipulators.first, C); + WM_manipulator_unlink(&mgroup->manipulators, mgroup->parent_mmap, mgroup->manipulators.first, C); } } @@ -614,7 +622,6 @@ static void rna_manipulatorgroup_setup_cb(const bContext *C, wmManipulatorGroup static wmKeyMap *rna_manipulatorgroup_setup_keymap_cb(const wmManipulatorGroupType *wgt, wmKeyConfig *config) { extern FunctionRNA rna_ManipulatorGroup_setup_keymap_func; - const char *wgroupname = wgt->name; void *ret; PointerRNA ptr; @@ -626,7 +633,6 @@ static wmKeyMap *rna_manipulatorgroup_setup_keymap_cb(const wmManipulatorGroupTy RNA_parameter_list_create(&list, &ptr, func); RNA_parameter_set_lookup(&list, "keyconfig", &config); - RNA_parameter_set_lookup(&list, "manipulator_group", &wgroupname); wgt->ext.call(NULL, &ptr, func, &list); RNA_parameter_get_lookup(&list, "keymap", &ret); @@ -825,7 +831,6 @@ static void rna_def_manipulators(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Add manipulator"); RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_string(func, "type", "Type", 0, "", "Manipulator identifier"); /* optional */ - RNA_def_string(func, "name", "Name", 0, "", "Manipulator name"); /* optional */ parm = RNA_def_pointer(func, "manipulator", "Manipulator", "", "New manipulator"); RNA_def_function_return(func, parm); @@ -914,11 +919,12 @@ static void rna_def_manipulator(BlenderRNA *brna, PropertyRNA *cprop) /* wmManipulator.handler */ static EnumPropertyItem tweak_actions[] = { {WM_MANIPULATOR_TWEAK_PRECISE, "PRECISE", 0, "Precise", ""}, + {WM_MANIPULATOR_TWEAK_SNAP, "SNAP", 0, "Snap", ""}, {0, NULL, 0, NULL, NULL} }; func = RNA_def_function(srna, "modal", NULL); RNA_def_function_ui_description(func, ""); - RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_pointer(func, "event", "Event", "", ""); @@ -934,12 +940,12 @@ static void rna_def_manipulator(BlenderRNA *brna, PropertyRNA *cprop) /* wmManipulator.setup */ func = RNA_def_function(srna, "setup", NULL); RNA_def_function_ui_description(func, ""); - RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); /* wmManipulator.invoke */ func = RNA_def_function(srna, "invoke", NULL); RNA_def_function_ui_description(func, ""); - RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_pointer(func, "event", "Event", "", ""); @@ -948,7 +954,7 @@ static void rna_def_manipulator(BlenderRNA *brna, PropertyRNA *cprop) /* wmManipulator.exit */ func = RNA_def_function(srna, "exit", NULL); RNA_def_function_ui_description(func, ""); - RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_boolean(func, "cancel", 0, "Cancel, otherwise confirm", ""); @@ -957,42 +963,48 @@ static void rna_def_manipulator(BlenderRNA *brna, PropertyRNA *cprop) /* wmManipulator.cursor_get */ /* TODO */ - /* wmManipulator.select */ - /* TODO, de-duplicate! */ - static EnumPropertyItem select_actions[] = { - {SEL_TOGGLE, "TOGGLE", 0, "Toggle", "Toggle selection for all elements"}, - {SEL_SELECT, "SELECT", 0, "Select", "Select all elements"}, - {SEL_DESELECT, "DESELECT", 0, "Deselect", "Deselect all elements"}, - {SEL_INVERT, "INVERT", 0, "Invert", "Invert selection of all elements"}, - {0, NULL, 0, NULL, NULL} - }; - func = RNA_def_function(srna, "select", NULL); + /* wmManipulator.select_refresh */ + func = RNA_def_function(srna, "select_refresh", NULL); RNA_def_function_ui_description(func, ""); - RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); - parm = RNA_def_pointer(func, "context", "Context", "", ""); - RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); - parm = RNA_def_enum(func, "action", select_actions, 0, "Action", "Selection action to execute"); - RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); /* -------------------------------------------------------------------- */ /* Instance Variables */ - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_property_string_funcs( - prop, "rna_Manipulator_name_get", "rna_Manipulator_name_length", "rna_Manipulator_name_set"); - RNA_def_property_ui_text(prop, "Name", ""); - RNA_def_struct_name_property(srna, prop); - RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL); + prop = RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "ManipulatorGroup"); + RNA_def_property_pointer_funcs(prop, "rna_Manipulator_group_get", NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "", "Manipulator group this manipulator is a member of"); + /* Color & Alpha */ prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_array(prop, 4); + RNA_def_property_array(prop, 3); RNA_def_property_float_funcs(prop, "rna_Manipulator_color_get", "rna_Manipulator_color_set", NULL); + prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE); + RNA_def_property_ui_text(prop, "Alpha", ""); + RNA_def_property_float_funcs(prop, "rna_Manipulator_alpha_get", "rna_Manipulator_alpha_set", NULL); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL); + + /* Color & Alpha (highlight) */ prop = RNA_def_property(srna, "color_highlight", PROP_FLOAT, PROP_COLOR); - RNA_def_property_array(prop, 4); + RNA_def_property_array(prop, 3); RNA_def_property_float_funcs(prop, "rna_Manipulator_color_hi_get", "rna_Manipulator_color_hi_set", NULL); - RNA_def_property_ui_text(prop, "Color", ""); + + prop = RNA_def_property(srna, "alpha_highlight", PROP_FLOAT, PROP_NONE); + RNA_def_property_ui_text(prop, "Alpha", ""); + RNA_def_property_float_funcs(prop, "rna_Manipulator_alpha_hi_get", "rna_Manipulator_alpha_hi_set", NULL); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL); + + prop = RNA_def_property(srna, "matrix_space", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4); + RNA_def_property_ui_text(prop, "Space Matrix", ""); + RNA_def_property_float_funcs(prop, "rna_Manipulator_matrix_space_get", "rna_Manipulator_matrix_space_set", NULL); + RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL); prop = RNA_def_property(srna, "matrix_basis", PROP_FLOAT, PROP_MATRIX); RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4); @@ -1006,13 +1018,13 @@ static void rna_def_manipulator(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_float_funcs(prop, "rna_Manipulator_matrix_offset_get", "rna_Manipulator_matrix_offset_set", NULL); RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL); - prop = RNA_def_property(srna, "scale_basis", PROP_FLOAT, PROP_MATRIX); + prop = RNA_def_property(srna, "scale_basis", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_text(prop, "Scale Basis", ""); RNA_def_property_float_funcs(prop, "rna_Manipulator_scale_basis_get", "rna_Manipulator_scale_basis_set", NULL); RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL); - prop = RNA_def_property(srna, "line_width", PROP_FLOAT, PROP_MATRIX); + prop = RNA_def_property(srna, "line_width", PROP_FLOAT, PROP_PIXEL); RNA_def_property_ui_text(prop, "Line Width", ""); RNA_def_property_float_funcs(prop, "rna_Manipulator_line_width_get", "rna_Manipulator_line_width_set", NULL); RNA_def_property_range(prop, 0.0f, FLT_MAX); @@ -1031,10 +1043,10 @@ static void rna_def_manipulator(BlenderRNA *brna, PropertyRNA *cprop) prop, "rna_Manipulator_flag_use_draw_hover_get", "rna_Manipulator_flag_use_draw_hover_set"); RNA_def_property_ui_text(prop, "Draw Hover", ""); RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL); - /* WM_MANIPULATOR_DRAW_ACTIVE */ - prop = RNA_def_property(srna, "use_draw_active", PROP_BOOLEAN, PROP_NONE); + /* WM_MANIPULATOR_DRAW_MODAL */ + prop = RNA_def_property(srna, "use_draw_modal", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs( - prop, "rna_Manipulator_flag_use_draw_active_get", "rna_Manipulator_flag_use_draw_active_set"); + prop, "rna_Manipulator_flag_use_draw_modal_get", "rna_Manipulator_flag_use_draw_modal_set"); RNA_def_property_ui_text(prop, "Draw Active", "Draw while dragging"); RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL); /* WM_MANIPULATOR_DRAW_VALUE */ @@ -1050,16 +1062,16 @@ static void rna_def_manipulator(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_boolean_funcs(prop, "rna_Manipulator_state_is_highlight_get", NULL); RNA_def_property_ui_text(prop, "Highlight", ""); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - /* WM_MANIPULATOR_STATE_ACTIVE */ - prop = RNA_def_property(srna, "is_active", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_Manipulator_state_is_active_get", NULL); + /* WM_MANIPULATOR_STATE_MODAL */ + prop = RNA_def_property(srna, "is_modal", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_Manipulator_state_is_modal_get", NULL); RNA_def_property_ui_text(prop, "Highlight", ""); RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* WM_MANIPULATOR_STATE_SELECT */ + /* (note that setting is involved, needs to handle array) */ prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_Manipulator_state_select_get", NULL); + RNA_def_property_boolean_funcs(prop, "rna_Manipulator_state_select_get", "rna_Manipulator_state_select_set"); RNA_def_property_ui_text(prop, "Select", ""); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_api_manipulator(srna); @@ -1134,6 +1146,8 @@ static void rna_def_manipulatorgroup(BlenderRNA *brna) "Supports selection"}, {WM_MANIPULATORGROUPTYPE_PERSISTENT, "PERSISTENT", 0, "Persistent", ""}, + {WM_MANIPULATORGROUPTYPE_DRAW_MODAL_ALL, "SHOW_MODAL_ALL", 0, "Show Modal All", + "Show all while interacting"}, {0, NULL, 0, NULL, NULL} }; prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE); @@ -1155,18 +1169,14 @@ static void rna_def_manipulatorgroup(BlenderRNA *brna) parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); - /* keymap_init */ + /* setup_keymap */ func = RNA_def_function(srna, "setup_keymap", NULL); RNA_def_function_ui_description( func, "Initialize keymaps for this manipulator group, use fallback keymap when not present"); RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL); - parm = RNA_def_pointer(func, "keyconf", "KeyConfig", "", ""); + parm = RNA_def_pointer(func, "keyconfig", "KeyConfig", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); - parm = RNA_def_property(func, "manipulator_group", PROP_STRING, PROP_NONE); - RNA_def_property_ui_text(parm, "Manipulator Group", "Manipulator Group ID"); - // RNA_def_property_string_default(parm, ""); - RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); /* return */ parm = RNA_def_pointer(func, "keymap", "KeyMap", "", ""); RNA_def_property_flag(parm, PROP_NEVER_NULL); diff --git a/source/blender/makesrna/intern/rna_wm_manipulator_api.c b/source/blender/makesrna/intern/rna_wm_manipulator_api.c index 9f011ad7b7d..7c805512e0b 100644 --- a/source/blender/makesrna/intern/rna_wm_manipulator_api.c +++ b/source/blender/makesrna/intern/rna_wm_manipulator_api.c @@ -68,7 +68,7 @@ static void rna_manipulator_draw_preset_facemap( wmManipulator *mpr, struct bContext *C, struct Object *ob, int facemap, int select_id) { struct Scene *scene = CTX_data_scene(C); - ED_manipulator_draw_preset_facemap(mpr, scene, ob, facemap, select_id); + ED_manipulator_draw_preset_facemap(C, mpr, scene, ob, facemap, select_id); } static void rna_manipulator_target_set_prop( diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 8f26077ea82..7530cc4427b 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -110,8 +110,8 @@ static void updateDepsgraph(ModifierData *md, } } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) @@ -131,7 +131,7 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct BMEditMesh *em, + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *em, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { ArmatureModifierData *amd = (ArmatureModifierData *) md; @@ -154,7 +154,7 @@ static void deformVertsEM( } static void deformMatricesEM( - ModifierData *md, Object *ob, struct BMEditMesh *em, + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *em, DerivedMesh *derivedData, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts) { @@ -169,7 +169,7 @@ static void deformMatricesEM( if (!derivedData) dm->release(dm); } -static void deformMatrices(ModifierData *md, Object *ob, DerivedMesh *derivedData, +static void deformMatrices(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts) { ArmatureModifierData *amd = (ArmatureModifierData *) md; diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 57f90fb4b51..fcd38f904d8 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -356,7 +356,7 @@ static void dm_merge_transform( } static DerivedMesh *arrayModifier_doArray( - ArrayModifierData *amd, + ArrayModifierData *amd, EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm, ModifierApplyFlag flag) { @@ -462,7 +462,7 @@ static DerivedMesh *arrayModifier_doArray( if (cu) { #ifdef CYCLIC_DEPENDENCY_WORKAROUND if (amd->curve_ob->curve_cache == NULL) { - BKE_displist_make_curveTypes(scene, amd->curve_ob, false); + BKE_displist_make_curveTypes(eval_ctx, scene, amd->curve_ob, false); } #endif @@ -725,12 +725,12 @@ static DerivedMesh *arrayModifier_doArray( } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *dm, +static DerivedMesh *applyModifier(ModifierData *md, EvaluationContext *eval_ctx, + Object *ob, DerivedMesh *dm, ModifierApplyFlag flag) { ArrayModifierData *amd = (ArrayModifierData *) md; - return arrayModifier_doArray(amd, md->scene, ob, dm, flag); + return arrayModifier_doArray(amd, eval_ctx, md->scene, ob, dm, flag); } diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 17b0cd4d7f5..b0433cac569 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -94,8 +94,8 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) /* * This calls the new bevel code (added since 2.64) */ -static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob, - DerivedMesh *dm, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + struct Object *ob, DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *result; diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index e649c8821fa..22609ec46b7 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -402,8 +402,8 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED( } static DerivedMesh *applyModifier( - ModifierData *md, Object *ob, - DerivedMesh *derivedData, + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, ModifierApplyFlag flag) { BooleanModifierData *bmd = (BooleanModifierData *)md; diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c index 061b1198f7e..49010664aa8 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ b/source/blender/modifiers/intern/MOD_boolean_util.c @@ -390,6 +390,9 @@ static void exporter_InitGeomArrays(ExportMeshData *export_data, * the operand. Data for those layers will not be allocated or initialized. */ + CustomData_merge(&dm_left->vertData, &dm->vertData, merge_mask, CD_DEFAULT, num_verts); + CustomData_merge(&dm_right->vertData, &dm->vertData, merge_mask, CD_DEFAULT, num_verts); + CustomData_merge(&dm_left->loopData, &dm->loopData, merge_mask, CD_DEFAULT, num_loops); CustomData_merge(&dm_right->loopData, &dm->loopData, merge_mask, CD_DEFAULT, num_loops); diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index d2467a8fc4a..640412e1d27 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -47,6 +47,8 @@ #include "BKE_particle.h" #include "BKE_scene.h" + + #ifdef _OPENMP # include "BKE_mesh.h" /* BKE_MESH_OMP_LIMIT */ #endif @@ -73,8 +75,8 @@ static bool dependsOnTime(ModifierData *UNUSED(md)) return true; } -static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), - DerivedMesh *derivedData, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *UNUSED(ob), DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm = derivedData; diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index 2dcc01b89d9..c2515c5f5de 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -433,8 +433,8 @@ static void cuboid_do( } } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) @@ -456,7 +456,8 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct BMEditMesh *editData, + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, false, false); diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c index 00161366b93..10603e6dccf 100644 --- a/source/blender/modifiers/intern/MOD_cloth.c +++ b/source/blender/modifiers/intern/MOD_cloth.c @@ -43,7 +43,6 @@ #include "BLI_utildefines.h" - #include "BKE_cloth.h" #include "BKE_cdderivedmesh.h" #include "BKE_effect.h" @@ -70,7 +69,7 @@ static void initData(ModifierData *md) cloth_init(clmd); } -static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], +static void deformVerts(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm; @@ -110,7 +109,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, CDDM_apply_vert_coords(dm, vertexCos); - clothModifier_do(clmd, md->scene, ob, dm, vertexCos); + clothModifier_do(clmd, eval_ctx, md->scene, ob, dm, vertexCos); dm->release(dm); } diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index a2a4b2e1274..0e0e93fc727 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -40,7 +40,6 @@ #include "BLI_math.h" #include "BLI_utildefines.h" - #include "BKE_collision.h" #include "BKE_cdderivedmesh.h" #include "BKE_global.h" @@ -48,6 +47,8 @@ #include "BKE_pointcache.h" #include "BKE_scene.h" +#include "MOD_modifiertypes.h" + static void initData(ModifierData *md) { CollisionModifierData *collmd = (CollisionModifierData *) md; @@ -97,8 +98,8 @@ static bool dependsOnTime(ModifierData *UNUSED(md)) return true; } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int UNUSED(numVerts), ModifierApplyFlag UNUSED(flag)) diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c index 0718b0f85fa..831b3034235 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.c +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c @@ -713,7 +713,7 @@ error: static void deformVerts( - ModifierData *md, Object *ob, DerivedMesh *derivedData, + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false); @@ -727,7 +727,7 @@ static void deformVerts( static void deformVertsEM( - ModifierData *md, Object *ob, struct BMEditMesh *editData, + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, false, false); diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index 3200caedc32..c232a32fe00 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -48,6 +48,8 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" +#include "MOD_modifiertypes.h" + static void initData(ModifierData *md) { CurveModifierData *cmd = (CurveModifierData *) md; @@ -113,8 +115,8 @@ static void updateDepsgraph(ModifierData *md, DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, "Curve Modifier"); } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *eval_ctx, + Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) @@ -123,19 +125,19 @@ static void deformVerts(ModifierData *md, Object *ob, /* silly that defaxis and curve_deform_verts are off by 1 * but leave for now to save having to call do_versions */ - curve_deform_verts(md->scene, cmd->object, ob, derivedData, vertexCos, numVerts, + curve_deform_verts(eval_ctx, md->scene, cmd->object, ob, derivedData, vertexCos, numVerts, cmd->name, cmd->defaxis - 1); } static void deformVertsEM( - ModifierData *md, Object *ob, struct BMEditMesh *em, + ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *em, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = derivedData; if (!derivedData) dm = CDDM_from_editbmesh(em, false, false); - deformVerts(md, ob, dm, vertexCos, numVerts, 0); + deformVerts(md, eval_ctx, ob, dm, vertexCos, numVerts, 0); if (!derivedData) dm->release(dm); } diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c index 9fd23598cb6..89ae1d364cf 100644 --- a/source/blender/modifiers/intern/MOD_datatransfer.c +++ b/source/blender/modifiers/intern/MOD_datatransfer.c @@ -152,7 +152,7 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams)) DT_TYPE_SHARP_FACE \ ) -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { DataTransferModifierData *dtmd = (DataTransferModifierData *) md; @@ -184,7 +184,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der BKE_reports_init(&reports, RPT_STORE); /* Note: no islands precision for now here. */ - BKE_object_data_transfer_dm(md->scene, dtmd->ob_source, ob, dm, dtmd->data_types, false, + BKE_object_data_transfer_dm(eval_ctx, md->scene, dtmd->ob_source, ob, dm, dtmd->data_types, false, dtmd->vmap_mode, dtmd->emap_mode, dtmd->lmap_mode, dtmd->pmap_mode, space_transform, false, max_dist, dtmd->map_ray_radius, 0.0f, dtmd->layers_select_src, dtmd->layers_select_dst, diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index bcb52e4e0ca..80e1b09ddb5 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -86,8 +86,8 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) return dataMask; } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { DecimateModifierData *dmd = (DecimateModifierData *) md; diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index c422aa05b12..a1f526507f9 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -375,8 +375,8 @@ static void displaceModifier_do( } } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) @@ -391,7 +391,7 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct BMEditMesh *editData, + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = get_cddm(ob, editData, derivedData, vertexCos, dependsOnNormals(md)); diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c index ade416f39eb..3c5afc6bb69 100644 --- a/source/blender/modifiers/intern/MOD_dynamicpaint.c +++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c @@ -41,8 +41,11 @@ #include "BKE_library_query.h" #include "BKE_modifier.h" +#include "DEG_depsgraph.h" + #include "DEG_depsgraph_build.h" +#include "MOD_modifiertypes.h" static void initData(ModifierData *md) { @@ -111,15 +114,15 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) return dataMask; } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *dm, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *eval_ctx, + Object *ob, DerivedMesh *dm, ModifierApplyFlag flag) { DynamicPaintModifierData *pmd = (DynamicPaintModifierData *) md; /* dont apply dynamic paint on orco dm stack */ if (!(flag & MOD_APPLY_ORCO)) { - return dynamicPaint_Modifier_do(pmd, md->scene, BKE_scene_layer_context_active_PLACEHOLDER(md->scene), ob, dm); + return dynamicPaint_Modifier_do(pmd, eval_ctx, md->scene, ob, dm); } return dm; } diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index f239807a7d3..bee65cb0f4a 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -48,6 +48,7 @@ #include "DNA_object_types.h" +#include "MOD_modifiertypes.h" static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd) { @@ -120,7 +121,8 @@ static void copyData(ModifierData *md, ModifierData *target) modifier_copyData_generic(md, target); } -static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), DerivedMesh *dm, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *UNUSED(ob), DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *result; diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 24ce2e3cc8e..3d013d273d0 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -51,9 +51,9 @@ #include "BKE_particle.h" #include "BKE_scene.h" - #include "MEM_guardedalloc.h" +#include "MOD_modifiertypes.h" static void initData(ModifierData *md) { @@ -786,8 +786,8 @@ static DerivedMesh *cutEdges(ExplodeModifierData *emd, DerivedMesh *dm) return splitdm; } static DerivedMesh *explodeMesh(ExplodeModifierData *emd, - ParticleSystemModifierData *psmd, Scene *scene, Object *ob, - DerivedMesh *to_explode) + ParticleSystemModifierData *psmd, struct EvaluationContext *eval_ctx, Scene *scene, + Object *ob, DerivedMesh *to_explode) { DerivedMesh *explode, *dm = to_explode; MFace *mf = NULL, *mface; @@ -812,6 +812,7 @@ static DerivedMesh *explodeMesh(ExplodeModifierData *emd, mface = dm->getTessFaceArray(dm); totpart = psmd->psys->totpart; + sim.eval_ctx = eval_ctx; sim.scene = scene; sim.ob = ob; sim.psys = psmd->psys; @@ -993,8 +994,8 @@ static ParticleSystemModifierData *findPrecedingParticlesystem(Object *ob, Modif } return psmd; } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *eval_ctx, + Object *ob, DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm = derivedData; @@ -1028,7 +1029,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, if (emd->flag & eExplodeFlag_EdgeCut) { int *facepa = emd->facepa; DerivedMesh *splitdm = cutEdges(emd, dm); - DerivedMesh *explode = explodeMesh(emd, psmd, md->scene, ob, splitdm); + DerivedMesh *explode = explodeMesh(emd, psmd, eval_ctx, md->scene, ob, splitdm); MEM_freeN(emd->facepa); emd->facepa = facepa; @@ -1036,7 +1037,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, return explode; } else - return explodeMesh(emd, psmd, md->scene, ob, derivedData); + return explodeMesh(emd, psmd, eval_ctx, md->scene, ob, derivedData); } return derivedData; } diff --git a/source/blender/modifiers/intern/MOD_fluidsim.c b/source/blender/modifiers/intern/MOD_fluidsim.c index 85eb7b2ffc9..4a6c2328d53 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim.c +++ b/source/blender/modifiers/intern/MOD_fluidsim.c @@ -47,6 +47,8 @@ #include "DEG_depsgraph_build.h" #include "MOD_fluidsim_util.h" +#include "MOD_modifiertypes.h" + #include "MEM_guardedalloc.h" /* Fluidsim */ @@ -80,8 +82,8 @@ static void copyData(ModifierData *md, ModifierData *target) -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *dm, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *dm, ModifierApplyFlag flag) { FluidsimModifierData *fluidmd = (FluidsimModifierData *) md; diff --git a/source/blender/modifiers/intern/MOD_hair.c b/source/blender/modifiers/intern/MOD_hair.c index e87ee4c6116..a31303cdce8 100644 --- a/source/blender/modifiers/intern/MOD_hair.c +++ b/source/blender/modifiers/intern/MOD_hair.c @@ -94,8 +94,8 @@ static void freeData(ModifierData *md) } } -static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), - DerivedMesh *dm, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *UNUSED(ob), DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) { HairModifierData *hmd = (HairModifierData *) md; diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 08103292a8b..354b131c74b 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -46,7 +46,6 @@ #include "BKE_deform.h" #include "BKE_colortools.h" - #include "MEM_guardedalloc.h" #include "MOD_util.h" @@ -357,7 +356,7 @@ static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm, } } -static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { @@ -373,7 +372,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, dm->release(dm); } -static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editData, +static void deformVertsEM(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { HookModifierData *hmd = (HookModifierData *) md; diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c index 56a2e217a2a..47ce14efc1f 100644 --- a/source/blender/modifiers/intern/MOD_laplaciandeform.c +++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c @@ -724,7 +724,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) return dataMask; } -static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false); @@ -736,7 +736,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, } static void deformVertsEM( - ModifierData *md, Object *ob, struct BMEditMesh *editData, + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, false, false); diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c index 1295a75d9e7..66cc3deb727 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c @@ -506,7 +506,7 @@ static CustomDataMask required_data_mask(Object *UNUSED(ob), ModifierData *md) return dataMask; } -static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm; @@ -524,7 +524,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, } static void deformVertsEM( - ModifierData *md, Object *ob, struct BMEditMesh *editData, + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm; diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index 8c723f1c4be..d150bf3c8e0 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -103,8 +103,8 @@ static void updateDepsgraph(ModifierData *md, DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, "Lattice Modifier"); } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) @@ -119,14 +119,14 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct BMEditMesh *em, + ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *em, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = derivedData; if (!derivedData) dm = CDDM_from_editbmesh(em, false, false); - deformVerts(md, ob, dm, vertexCos, numVerts, 0); + deformVerts(md, eval_ctx, ob, dm, vertexCos, numVerts, 0); if (!derivedData) dm->release(dm); } diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c index 11c0fae9a75..b66007b8a87 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -52,6 +52,8 @@ #include "DEG_depsgraph_build.h" +#include "MOD_modifiertypes.h" + #include "BLI_strict_flags.h" static void copyData(ModifierData *md, ModifierData *target) @@ -92,8 +94,8 @@ static void updateDepsgraph(ModifierData *md, } } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *dm, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) { MaskModifierData *mmd = (MaskModifierData *)md; diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c index 0d96032c515..4c377f7fe90 100644 --- a/source/blender/modifiers/intern/MOD_meshcache.c +++ b/source/blender/modifiers/intern/MOD_meshcache.c @@ -272,8 +272,8 @@ static void meshcache_do( } } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) @@ -284,7 +284,7 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct BMEditMesh *UNUSED(editData), + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md; diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 3c05f8266f0..35fc40b82d3 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -272,7 +272,7 @@ static void meshdeform_vert_task(void *userdata, const int iter) } static void meshdeformModifier_do( - ModifierData *md, Object *ob, DerivedMesh *dm, + ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { MeshDeformModifierData *mmd = (MeshDeformModifierData *) md; @@ -299,7 +299,7 @@ static void meshdeformModifier_do( */ if (mmd->object == md->scene->obedit) { BMEditMesh *em = BKE_editmesh_from_object(mmd->object); - tmpdm = editbmesh_get_derived_cage_and_final(md->scene, mmd->object, em, 0, &cagedm); + tmpdm = editbmesh_get_derived_cage_and_final(eval_ctx, md->scene, mmd->object, em, 0, &cagedm); if (tmpdm) tmpdm->release(tmpdm); } @@ -402,7 +402,7 @@ static void meshdeformModifier_do( cagedm->release(cagedm); } -static void deformVerts(ModifierData *md, Object *ob, +static void deformVerts(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, @@ -412,13 +412,13 @@ static void deformVerts(ModifierData *md, Object *ob, modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */ - meshdeformModifier_do(md, ob, dm, vertexCos, numVerts); + meshdeformModifier_do(md, eval_ctx, ob, dm, vertexCos, numVerts); if (dm && dm != derivedData) dm->release(dm); } -static void deformVertsEM(ModifierData *md, Object *ob, +static void deformVertsEM(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData, float (*vertexCos)[3], @@ -426,7 +426,7 @@ static void deformVertsEM(ModifierData *md, Object *ob, { DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false); - meshdeformModifier_do(md, ob, dm, vertexCos, numVerts); + meshdeformModifier_do(md, eval_ctx, ob, dm, vertexCos, numVerts); if (dm && dm != derivedData) dm->release(dm); diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c index df13cadd184..5d623295edf 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.c +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c @@ -92,8 +92,8 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams)) return (mcmd->cache_file == NULL) || (mcmd->object_path[0] == '\0'); } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *dm, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *dm, ModifierApplyFlag flag) { #ifdef WITH_ALEMBIC diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index e0c37e8a0ce..a9e07fe4448 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -47,6 +47,8 @@ #include "DEG_depsgraph_build.h" +#include "MOD_modifiertypes.h" + static void initData(ModifierData *md) { MirrorModifierData *mmd = (MirrorModifierData *) md; @@ -319,8 +321,8 @@ static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, return result; } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *result; diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index aba184b7d40..b63b507586c 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -46,6 +46,8 @@ #include "BKE_modifier.h" #include "BKE_subsurf.h" +#include "MOD_modifiertypes.h" + static void initData(ModifierData *md) { MultiresModifierData *mmd = (MultiresModifierData *)md; @@ -65,8 +67,8 @@ static void copyData(ModifierData *md, ModifierData *target) modifier_copyData_generic(md, target); } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, - ModifierApplyFlag flag) +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, + DerivedMesh *dm, ModifierApplyFlag flag) { MultiresModifierData *mmd = (MultiresModifierData *)md; DerivedMesh *result; diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c index fa4d33f2e95..ca6aa71eb37 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.c +++ b/source/blender/modifiers/intern/MOD_normal_edit.c @@ -521,7 +521,8 @@ static void updateDepsgraph(ModifierData *md, } } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, + DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) { return normalEditModifier_do((NormalEditModifierData *)md, ob, dm); } diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 120337eb2ea..878f17dd04a 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -44,6 +44,8 @@ #include "BKE_modifier.h" #include "BKE_ocean.h" +#include "MOD_modifiertypes.h" + #ifdef WITH_OCEANSIM static void init_cache_data(Object *ob, struct OceanModifierData *omd) { @@ -540,8 +542,8 @@ static DerivedMesh *doOcean(ModifierData *md, Object *UNUSED(ob), } #endif /* WITH_OCEANSIM */ -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *result; diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 316d51b9581..f25b6b225a5 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -53,6 +53,8 @@ #include "DEG_depsgraph_build.h" +#include "MOD_modifiertypes.h" + static void initData(ModifierData *md) { ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md; @@ -164,8 +166,8 @@ static int particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *psy return 0; } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *eval_ctx, + Object *ob, DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm = derivedData, *result; @@ -210,6 +212,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, if (totpart == 0) return derivedData; + sim.eval_ctx = eval_ctx; sim.scene = md->scene; sim.ob = pimd->ob; sim.psys = psys; diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index a3b9d808b17..777487fabcf 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -97,8 +97,8 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) } /* saves the current emitter state for a particle system and calculates particles */ -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *eval_ctx, + Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int UNUSED(numVerts), ModifierApplyFlag flag) @@ -186,7 +186,7 @@ static void deformVerts(ModifierData *md, Object *ob, if (!(ob->transflag & OB_NO_PSYS_UPDATE)) { psmd->flag &= ~eParticleSystemFlag_psys_updated; - particle_system_update(md->scene, ob, psys, (flag & MOD_APPLY_RENDER) != 0); + particle_system_update(eval_ctx, md->scene, ob, psys, (flag & MOD_APPLY_RENDER) != 0); psmd->flag |= eParticleSystemFlag_psys_updated; } } diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index fb5c12399a4..f5fa6abe37b 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -143,6 +143,7 @@ static void dualcon_add_quad(void *output_v, const int vert_indices[4]) } static DerivedMesh *applyModifier(ModifierData *md, + struct EvaluationContext *UNUSED(eval_ctx), Object *UNUSED(ob), DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) @@ -203,7 +204,9 @@ static DerivedMesh *applyModifier(ModifierData *md, #else /* !WITH_MOD_REMESH */ -static DerivedMesh *applyModifier(ModifierData *UNUSED(md), Object *UNUSED(ob), +static DerivedMesh *applyModifier(ModifierData *UNUSED(md), + struct EvaluationContext *UNUSED(eval_ctx), + Object *UNUSED(ob), DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index f62c68b56c9..04599fcb535 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -133,8 +133,8 @@ static void copyData(ModifierData *md, ModifierData *target) modifier_copyData_generic(md, target); } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, ModifierApplyFlag flag) { DerivedMesh *dm = derivedData; diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c index 6c8bd06c196..b5039669b63 100644 --- a/source/blender/modifiers/intern/MOD_shapekey.c +++ b/source/blender/modifiers/intern/MOD_shapekey.c @@ -44,8 +44,8 @@ #include "MOD_modifiertypes.h" -static void deformVerts(ModifierData *UNUSED(md), Object *ob, - DerivedMesh *UNUSED(derivedData), +static void deformVerts(ModifierData *UNUSED(md), struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *UNUSED(derivedData), float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) @@ -61,7 +61,7 @@ static void deformVerts(ModifierData *UNUSED(md), Object *ob, } } -static void deformMatrices(ModifierData *md, Object *ob, DerivedMesh *derivedData, +static void deformMatrices(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts) { Key *key = BKE_key_from_object(ob); @@ -80,10 +80,10 @@ static void deformMatrices(ModifierData *md, Object *ob, DerivedMesh *derivedDat copy_m3_m3(defMats[a], scale); } - deformVerts(md, ob, derivedData, vertexCos, numVerts, 0); + deformVerts(md, eval_ctx, ob, derivedData, vertexCos, numVerts, 0); } -static void deformVertsEM(ModifierData *md, Object *ob, +static void deformVertsEM(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData, float (*vertexCos)[3], @@ -92,11 +92,11 @@ static void deformVertsEM(ModifierData *md, Object *ob, Key *key = BKE_key_from_object(ob); if (key && key->type == KEY_RELATIVE) - deformVerts(md, ob, derivedData, vertexCos, numVerts, 0); + deformVerts(md, eval_ctx, ob, derivedData, vertexCos, numVerts, 0); } -static void deformMatricesEM(ModifierData *UNUSED(md), Object *ob, - struct BMEditMesh *UNUSED(editData), +static void deformMatricesEM(ModifierData *UNUSED(md), struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, struct BMEditMesh *UNUSED(editData), DerivedMesh *UNUSED(derivedData), float (*vertexCos)[3], float (*defMats)[3][3], diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index 32241d8390a..c197e2ff7b1 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -103,8 +103,8 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, walk(userData, ob, &smd->auxTarget, IDWALK_CB_NOP); } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag flag) @@ -124,7 +124,8 @@ static void deformVerts(ModifierData *md, Object *ob, dm->release(dm); } -static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, +static void deformVertsEM(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, + struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = derivedData; diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 4660afc0977..658c8b54c62 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -302,8 +302,8 @@ static void updateDepsgraph(ModifierData *md, } } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) @@ -322,8 +322,8 @@ static void deformVerts(ModifierData *md, Object *ob, dm->release(dm); } -static void deformVertsEM(ModifierData *md, Object *ob, - struct BMEditMesh *editData, +static void deformVertsEM(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 4b84aeb335a..92c4cea9c17 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -77,6 +77,8 @@ #include "BKE_mesh_mapping.h" #include "BKE_modifier.h" +#include "MOD_modifiertypes.h" + #include "bmesh.h" typedef struct { @@ -1915,6 +1917,7 @@ static void copyData(ModifierData *md, ModifierData *target) } static DerivedMesh *applyModifier(ModifierData *md, + struct EvaluationContext *UNUSED(eval_ctx), Object *UNUSED(ob), DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c index 1b9e06bf0dc..c2a43f8b42e 100644 --- a/source/blender/modifiers/intern/MOD_smoke.c +++ b/source/blender/modifiers/intern/MOD_smoke.c @@ -45,7 +45,6 @@ #include "BLI_utildefines.h" - #include "BKE_cdderivedmesh.h" #include "BKE_layer.h" #include "BKE_library.h" @@ -54,8 +53,11 @@ #include "BKE_modifier.h" #include "BKE_smoke.h" +#include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" +#include "MOD_modifiertypes.h" + static void initData(ModifierData *md) { SmokeModifierData *smd = (SmokeModifierData *) md; @@ -100,8 +102,8 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) return dataMask; } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *dm, +static DerivedMesh *applyModifier(ModifierData *md, EvaluationContext *eval_ctx, + Object *ob, DerivedMesh *dm, ModifierApplyFlag flag) { SmokeModifierData *smd = (SmokeModifierData *) md; @@ -109,7 +111,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, if (flag & MOD_APPLY_ORCO) return dm; - return smokeModifier_do(smd, md->scene, BKE_scene_layer_context_active_PLACEHOLDER(md->scene), ob, dm); + return smokeModifier_do(smd, eval_ctx, md->scene, ob, dm); } static bool dependsOnTime(ModifierData *UNUSED(md)) diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index f0f20acb8ea..148a0d01230 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -215,7 +215,7 @@ static void smoothModifier_do( MEM_freeN(uctmp); } -static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false); @@ -228,7 +228,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, } static void deformVertsEM( - ModifierData *md, Object *ob, struct BMEditMesh *editData, + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, false, false); diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c index 780a55aa631..f59d28fca84 100644 --- a/source/blender/modifiers/intern/MOD_softbody.c +++ b/source/blender/modifiers/intern/MOD_softbody.c @@ -44,17 +44,18 @@ #include "BKE_particle.h" #include "BKE_softbody.h" +#include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" #include "MOD_modifiertypes.h" -static void deformVerts(ModifierData *md, Object *ob, +static void deformVerts(ModifierData *md, EvaluationContext *eval_ctx, Object *ob, DerivedMesh *UNUSED(derivedData), float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { - sbObjectStep(md->scene, BKE_scene_layer_context_active_PLACEHOLDER(md->scene), ob, (float)md->scene->r.cfra, vertexCos, numVerts); + sbObjectStep(eval_ctx, md->scene, ob, (float)md->scene->r.cfra, vertexCos, numVerts); } static bool dependsOnTime(ModifierData *UNUSED(md)) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index e589cb7d713..1389622bdcb 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -205,8 +205,8 @@ BLI_INLINE void madd_v3v3short_fl(float r[3], const short a[3], const float f) } static DerivedMesh *applyModifier( - ModifierData *md, Object *ob, - DerivedMesh *dm, + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *result; diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index cee8dd301bf..93a2e1e1c06 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -98,8 +98,8 @@ static bool isDisabled(ModifierData *md, int useRenderParams) return get_render_subsurf_level(&md->scene->r, levels, useRenderParams != 0) == 0; } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static DerivedMesh *applyModifier(ModifierData *md, EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, ModifierApplyFlag flag) { SubsurfModifierData *smd = (SubsurfModifierData *) md; @@ -162,8 +162,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, return result; } -static DerivedMesh *applyModifierEM(ModifierData *md, Object *UNUSED(ob), - struct BMEditMesh *UNUSED(editData), +static DerivedMesh *applyModifierEM(ModifierData *md, EvaluationContext *UNUSED(eval_ctx), + Object *UNUSED(ob), struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData, ModifierApplyFlag flag) { diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c index ea68f540236..00ac9452be2 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -85,8 +85,8 @@ static bool dependsOnTime(ModifierData *UNUSED(md)) return true; } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int UNUSED(numVerts), ModifierApplyFlag UNUSED(flag)) diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index 9339d71524f..9a108df0bdd 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -1162,16 +1162,16 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un } } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *UNUSED(derivedData), +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *UNUSED(derivedData), float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { surfacedeformModifier_do(md, vertexCos, numVerts, ob); } -static void deformVertsEM(ModifierData *md, Object *ob, - struct BMEditMesh *UNUSED(editData), +static void deformVertsEM(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, struct BMEditMesh *UNUSED(editData), DerivedMesh *UNUSED(derivedData), float (*vertexCos)[3], int numVerts) { diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c index a5d826a69ba..9124032e3d8 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.c +++ b/source/blender/modifiers/intern/MOD_triangulate.c @@ -35,6 +35,8 @@ #include "bmesh.h" #include "bmesh_tools.h" +#include "MOD_modifiertypes.h" + static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int quad_method, const int ngon_method) { DerivedMesh *result; @@ -83,6 +85,7 @@ static void copyData(ModifierData *md, ModifierData *target) } static DerivedMesh *applyModifier(ModifierData *md, + struct EvaluationContext *UNUSED(eval_ctx), Object *UNUSED(ob), DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index cae83282238..473b3ec045c 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -335,8 +335,8 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, return dm; } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *result; diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c index 7ee0a7e3108..b24ea55696e 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.c +++ b/source/blender/modifiers/intern/MOD_uvwarp.c @@ -143,8 +143,8 @@ static void uv_warp_compute(void *userdata, const int i) } } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, - DerivedMesh *dm, +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) { UVWarpModifierData *umd = (UVWarpModifierData *) md; diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index c9a9e20df23..b275d02f5a8 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -313,7 +313,7 @@ static int warp_needs_dm(WarpModifierData *wmd) return wmd->texture || wmd->defgrp_name[0]; } -static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm = NULL; @@ -330,7 +330,7 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, } } -static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *em, +static void deformVertsEM(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *em, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = derivedData; @@ -341,7 +341,7 @@ static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *em, dm = CDDM_from_editbmesh(em, false, false); } - deformVerts(md, ob, dm, vertexCos, numVerts, 0); + deformVerts(md, eval_ctx, ob, dm, vertexCos, numVerts, 0); if (use_dm) { if (!derivedData) dm->release(dm); diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index 73e96f87c66..6d3f621105c 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -314,8 +314,8 @@ static void waveModifier_do(WaveModifierData *md, if (wmd->texture) MEM_freeN(tex_co); } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, +static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) @@ -335,7 +335,7 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct BMEditMesh *editData, + ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = derivedData; diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index e6603b81bfd..af92277bb30 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -49,7 +49,9 @@ #include "DEG_depsgraph_build.h" #include "MEM_guardedalloc.h" + #include "MOD_weightvg_util.h" +#include "MOD_modifiertypes.h" /************************************** * Modifiers functions. * @@ -164,7 +166,10 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams)) return (wmd->defgrp_name[0] == '\0'); } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, +static DerivedMesh *applyModifier(ModifierData *md, + struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, + DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md; diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index df07cffe63f..75edc216879 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -46,7 +46,9 @@ #include "DEG_depsgraph_build.h" #include "MEM_guardedalloc.h" + #include "MOD_weightvg_util.h" +#include "MOD_modifiertypes.h" /** @@ -215,8 +217,8 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams)) return (wmd->defgrp_name_a[0] == '\0'); } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, - ModifierApplyFlag UNUSED(flag)) +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, + DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md; DerivedMesh *dm = derivedData; diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index 70b413ca685..4c8a1be5ceb 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -50,7 +50,9 @@ #include "DEG_depsgraph_build.h" #include "MEM_guardedalloc.h" + #include "MOD_weightvg_util.h" +#include "MOD_modifiertypes.h" //#define USE_TIMEIT @@ -372,8 +374,8 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams)) return (wmd->proximity_ob_target == NULL); } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, - ModifierApplyFlag UNUSED(flag)) +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, + DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md; DerivedMesh *dm = derivedData; diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c index 0c295f91012..b5825d9aab2 100644 --- a/source/blender/modifiers/intern/MOD_wireframe.c +++ b/source/blender/modifiers/intern/MOD_wireframe.c @@ -107,7 +107,8 @@ static DerivedMesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob, } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) +static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, + DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) { return WireframeModifier_do((WireframeModifierData *)md, ob, dm); } diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index b5d77e99328..ec35959f31a 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -214,6 +214,9 @@ static void ntree_shader_link_builtin_normal(bNodeTree *ntree, * render engines works but it's how the GPU shader compilation works. This we * can change in the future and make it a generic function, but for now it stays * private here. + * + * It also does not yet take into account render engine specific output nodes, + * it should give priority to e.g. the Eevee material output node for Eevee. */ static bNode *ntree_shader_output_node(bNodeTree *ntree) { @@ -475,6 +478,48 @@ static void ntree_shader_relink_displacement(bNodeTree *ntree, ntreeUpdateTree(G.main, ntree); } +static bool ntree_tag_ssr_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *userdata, const bool UNUSED(reversed)) +{ + switch (fromnode->type) { + case SH_NODE_BSDF_ANISOTROPIC: + case SH_NODE_EEVEE_METALLIC: + case SH_NODE_EEVEE_SPECULAR: + case SH_NODE_BSDF_PRINCIPLED: + case SH_NODE_BSDF_GLOSSY: + fromnode->ssr_id = (*(float *)userdata); + (*(float *)userdata) += 1; + break; + default: + /* We could return false here but since we (will) + * allow the use of Closure as RGBA, we can have + * Bsdf nodes linked to other Bsdf nodes. */ + break; + } + + return true; +} + +/* EEVEE: Scan the ntree to set the Screen Space Reflection + * layer id of every specular node. + */ +static void ntree_shader_tag_ssr_node(bNodeTree *ntree, short compatibility) +{ + if (compatibility != NODE_NEWER_SHADING) { + /* We can only deal with new shading system here. */ + return; + } + + bNode *output_node = ntree_shader_output_node(ntree); + if (output_node == NULL) { + return; + } + /* Make sure sockets links pointers are correct. */ + ntreeUpdateTree(G.main, ntree); + + int lobe_count = 0; + nodeChainIter(ntree, output_node, ntree_tag_ssr_bsdf_cb, &lobe_count, true); +} + void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat, short compatibility) { /* localize tree to create links for reroute and mute */ @@ -486,6 +531,8 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat, short compatibili */ ntree_shader_relink_displacement(localtree, compatibility); + ntree_shader_tag_ssr_node(localtree, compatibility); + exec = ntreeShaderBeginExecTree(localtree); ntreeExecGPUNodes(exec, mat, 1, compatibility); ntreeShaderEndExecTree(exec); diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c index 456c000a39b..35121b2afed 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c @@ -51,7 +51,7 @@ static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat, bNode *node, bNodeExecD if (!in[2].link) GPU_link(mat, "world_normals_get", &in[2].link); - return GPU_stack_link(mat, node, "node_bsdf_glossy", in, out); + return GPU_stack_link(mat, node, "node_bsdf_glossy", in, out, GPU_uniform(&node->ssr_id)); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c index 4ae0474d685..1ec77bc9189 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c @@ -100,10 +100,10 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeE /* Only use complex versions when needed. */ if (!in[12].link && (in[12].vec[0] == 0.0f)) { - return GPU_stack_link(mat, node, "node_bsdf_principled_simple", in, out, GPU_builtin(GPU_VIEW_POSITION)); + return GPU_stack_link(mat, node, "node_bsdf_principled_simple", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_uniform(&node->ssr_id)); } else { - return GPU_stack_link(mat, node, "node_bsdf_principled_clearcoat", in, out, GPU_builtin(GPU_VIEW_POSITION)); + return GPU_stack_link(mat, node, "node_bsdf_principled_clearcoat", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_uniform(&node->ssr_id)); } } diff --git a/source/blender/nodes/shader/nodes/node_shader_eevee_metallic.c b/source/blender/nodes/shader/nodes/node_shader_eevee_metallic.c index 2a8a3a44f39..071486493fa 100644 --- a/source/blender/nodes/shader/nodes/node_shader_eevee_metallic.c +++ b/source/blender/nodes/shader/nodes/node_shader_eevee_metallic.c @@ -68,7 +68,7 @@ static int node_shader_gpu_eevee_metallic(GPUMaterial *mat, bNode *node, bNodeEx GPU_link(mat, "set_value", GPU_uniform(&one), &in[10].link); } - return GPU_stack_link(mat, node, "node_eevee_metallic", in, out); + return GPU_stack_link(mat, node, "node_eevee_metallic", in, out, GPU_uniform(&node->ssr_id)); } diff --git a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c index 954f9b3ee4a..c249e77c17a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c +++ b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c @@ -67,7 +67,7 @@ static int node_shader_gpu_eevee_specular(GPUMaterial *mat, bNode *node, bNodeEx GPU_link(mat, "set_value", GPU_uniform(&one), &in[9].link); } - return GPU_stack_link(mat, node, "node_eevee_specular", in, out); + return GPU_stack_link(mat, node, "node_eevee_specular", in, out, GPU_uniform(&node->ssr_id)); } diff --git a/source/blender/nodes/shader/nodes/node_shader_output_material.c b/source/blender/nodes/shader/nodes/node_shader_output_material.c index 953999a0d48..0418b039337 100644 --- a/source/blender/nodes/shader/nodes/node_shader_output_material.c +++ b/source/blender/nodes/shader/nodes/node_shader_output_material.c @@ -42,10 +42,6 @@ static int node_shader_gpu_output_material(GPUMaterial *mat, bNode *node, bNodeE { GPUNodeLink *outlink; - if (BKE_scene_uses_blender_eevee(GPU_material_scene(mat))) { - return false; - } - GPU_stack_link(mat, node, "node_output_material", in, out, &outlink); GPU_material_output_link(mat, outlink); diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 88445cfd62b..bfd0898f064 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -941,6 +941,8 @@ PyDoc_STRVAR(bpy_bmesh_from_object_doc, ); static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject *kw) { + /* TODO: This doesn't work currently because of eval_ctx. */ +#if 0 static const char *kwlist[] = {"object", "scene", "deform", "render", "cage", "face_normals", NULL}; PyObject *py_object; PyObject *py_scene; @@ -1033,6 +1035,10 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject dm->release(dm); Py_RETURN_NONE; +#else + UNUSED_VARS(self, args, kw); +#endif + return NULL; } diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index 47dead028a4..532f85f87d7 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -116,6 +116,9 @@ PyDoc_STRVAR(bpy_bmlayeraccess_collection__skin_doc, PyDoc_STRVAR(bpy_bmlayeraccess_collection__paint_mask_doc, "Accessor for paint mask layer.\n\ntype: :class:`BMLayerCollection`" ); +PyDoc_STRVAR(bpy_bmlayeraccess_collection__face_map_doc, +"FaceMap custom-data layer.\n\ntype: :class:`BMLayerCollection`" +); #ifdef WITH_FREESTYLE PyDoc_STRVAR(bpy_bmlayeraccess_collection__freestyle_edge_doc, "Accessor for Freestyle edge layer.\n\ntype: :class:`BMLayerCollection`" @@ -218,6 +221,7 @@ static PyGetSetDef bpy_bmlayeraccess_face_getseters[] = { {(char *)"float", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__float_doc, (void *)CD_PROP_FLT}, {(char *)"int", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__int_doc, (void *)CD_PROP_INT}, {(char *)"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__string_doc, (void *)CD_PROP_STR}, + {(char *)"face_map", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__face_map_doc, (void *)CD_FACEMAP}, #ifdef WITH_FREESTYLE {(char *)"freestyle", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)bpy_bmlayeraccess_collection__freestyle_face_doc, (void *)CD_FREESTYLE_FACE}, @@ -983,6 +987,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer) break; } case CD_PROP_INT: + case CD_FACEMAP: { ret = PyLong_FromLong(*(int *)value); break; @@ -1063,6 +1068,7 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj break; } case CD_PROP_INT: + case CD_FACEMAP: { int tmp_val = PyLong_AsLong(py_value); if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) { diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c index ed2752d8372..7ab6447d21a 100644 --- a/source/blender/python/generic/bpy_internal_import.c +++ b/source/blender/python/generic/bpy_internal_import.c @@ -248,8 +248,17 @@ PyObject *bpy_text_reimport(PyObject *module, int *found) if ((name = PyModule_GetName(module)) == NULL) return NULL; - if ((filepath = (char *)PyModule_GetFilename(module)) == NULL) - return NULL; + { + PyObject *module_file = PyModule_GetFilenameObject(module); + if (module_file == NULL) { + return NULL; + } + filepath = (char *)_PyUnicode_AsString(module_file); + Py_DECREF(module_file); + if (filepath == NULL) { + return NULL; + } + } /* look up the text object */ text = BLI_findstring(&maggie->text, BLI_path_basename(filepath), offsetof(ID, name) + 2); diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 2e789d6d4b3..861e2dbb0df 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -300,7 +300,14 @@ void PyC_FileAndNum(const char **filename, int *lineno) if (mod_name) { PyObject *mod = PyDict_GetItem(PyImport_GetModuleDict(), mod_name); if (mod) { - *filename = PyModule_GetFilename(mod); + PyObject *mod_file = PyModule_GetFilenameObject(mod); + if (mod_file) { + *filename = _PyUnicode_AsString(mod_name); + Py_DECREF(mod_file); + } + else { + PyErr_Clear(); + } } /* unlikely, fallback */ diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index 8b3464173d2..e47bf21f04b 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -89,6 +89,7 @@ static PyStructSequence_Field app_info_fields[] = { {(char *)"version_cycle", (char *)"The release status of this build alpha/beta/rc/release"}, {(char *)"binary_path", (char *)"The location of blenders executable, useful for utilities that spawn new instances"}, {(char *)"background", (char *)"Boolean, True when blender is running without a user interface (started with -b)"}, + {(char *)"factory_startup", (char *)"Boolean, True when blender is running with --factory-startup)"}, /* buildinfo */ {(char *)"build_date", (char *)"The date this blender instance was built"}, @@ -165,6 +166,7 @@ static PyObject *make_app_info(void) SetStrItem(STRINGIFY(BLENDER_VERSION_CYCLE)); SetStrItem(BKE_appdir_program_path()); SetObjItem(PyBool_FromLong(G.background)); + SetObjItem(PyBool_FromLong(G.factory_startup)); /* build info, use bytes since we can't assume _any_ encoding: * see patch [#30154] for issue */ diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index cd4d2f7a1c2..c6337f2ac28 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -870,6 +870,7 @@ static void bpy_module_delay_init(PyObject *bpy_proxy) BLI_strncpy(filename_abs, filename_rel, sizeof(filename_abs)); BLI_path_cwd(filename_abs, sizeof(filename_abs)); + Py_DECREF(filename_obj); argv[0] = filename_abs; argv[1] = NULL; diff --git a/source/blender/python/intern/bpy_manipulator_wrap.c b/source/blender/python/intern/bpy_manipulator_wrap.c index 7d02c2963d7..db9fcdb377a 100644 --- a/source/blender/python/intern/bpy_manipulator_wrap.c +++ b/source/blender/python/intern/bpy_manipulator_wrap.c @@ -143,27 +143,32 @@ static void manipulator_properties_init(wmManipulatorType *wt) * get direct from the dict to avoid raising a load of attribute errors (yes this isnt ideal) - campbell */ PyObject *py_class_dict = py_class->tp_dict; PyObject *bl_target_properties = PyDict_GetItem(py_class_dict, bpy_intern_str_bl_target_properties); - PyObject *bl_target_properties_fast; - if (!(bl_target_properties_fast = PySequence_Fast(bl_target_properties, "bl_target_properties sequence"))) { - /* PySequence_Fast sets the error */ - PyErr_Print(); - PyErr_Clear(); - return; - } - - const uint items_len = PySequence_Fast_GET_SIZE(bl_target_properties_fast); - PyObject **items = PySequence_Fast_ITEMS(bl_target_properties_fast); - - for (uint i = 0; i < items_len; i++) { - if (!bpy_manipulatortype_target_property_def(wt, items[i])) { + /* Some widgets may only exist to activate operators. */ + if (bl_target_properties != NULL) { + PyObject *bl_target_properties_fast; + if (!(bl_target_properties_fast = PySequence_Fast( + bl_target_properties, "bl_target_properties sequence"))) + { + /* PySequence_Fast sets the error */ PyErr_Print(); PyErr_Clear(); - break; + return; } - } - Py_DECREF(bl_target_properties_fast); + const uint items_len = PySequence_Fast_GET_SIZE(bl_target_properties_fast); + PyObject **items = PySequence_Fast_ITEMS(bl_target_properties_fast); + + for (uint i = 0; i < items_len; i++) { + if (!bpy_manipulatortype_target_property_def(wt, items[i])) { + PyErr_Print(); + PyErr_Clear(); + break; + } + } + + Py_DECREF(bl_target_properties_fast); + } } } diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index c7787ba9682..362c0281b36 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -2697,7 +2697,8 @@ PyDoc_STRVAR(BPy_EnumProperty_doc, " :icon: An icon string identifier or integer icon value\n" " (e.g. returned by :class:`bpy.types.UILayout.icon`)\n" " :number: Unique value used as the identifier for this item (stored in file data).\n" -" Use when the identifier may need to change.\n" +" Use when the identifier may need to change. If the *ENUM_FLAG* option is used,\n" +" the values are bitmasks and should be powers of two.\n" "\n" " When an item only contains 4 items they define ``(identifier, name, description, number)``.\n" "\n" diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 51e179fb317..e08f1bca10c 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -6657,7 +6657,30 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) if (ptr->data == NULL && ptr->type == NULL) { /* Operator RNA has NULL data */ Py_RETURN_NONE; } - else { + + /* New in 2.8x, since not many types support instancing + * we may want to use a flag to avoid looping over all classes. - campbell */ + void **instance = ptr->data ? RNA_struct_instance(ptr) : NULL; + if (instance && *instance) { + pyrna = *instance; + + /* Refine may have changed types after the first instance was created. */ + if (ptr->type == pyrna->ptr.type) { + Py_INCREF(pyrna); + return (PyObject *)pyrna; + } + else { + /* Existing users will need to use 'type_recast' method. */ + Py_DECREF(pyrna); + *instance = NULL; + /* Continue as if no instance was made */ +#if 0 /* no need to assign, will be written to next... */ + pyrna = NULL; +#endif + } + } + + { PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr); if (tp) { @@ -6678,6 +6701,12 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) return NULL; } + /* Blender's instance owns a reference (to avoid Python freeing it). */ + if (instance) { + *instance = pyrna; + Py_INCREF(pyrna); + } + pyrna->ptr = *ptr; #ifdef PYRNA_FREE_SUPPORT pyrna->freeptr = false; @@ -7450,7 +7479,6 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param PyObject *args; PyObject *ret = NULL, *py_srna = NULL, *py_class_instance = NULL, *parmitem; PyTypeObject *py_class; - void **py_class_instance_store = NULL; PropertyRNA *parm; ParameterIterator iter; PointerRNA funcptr; @@ -7501,10 +7529,6 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param py_class_instance = *instance; Py_INCREF(py_class_instance); } - else { - /* store the instance here once its created */ - py_class_instance_store = instance; - } } } /* end exception */ @@ -7575,10 +7599,6 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param if (py_class_instance == NULL) { err = -1; /* so the error is not overridden below */ } - else if (py_class_instance_store) { - *py_class_instance_store = py_class_instance; - Py_INCREF(py_class_instance); - } } } diff --git a/source/blender/python/intern/bpy_rna_driver.c b/source/blender/python/intern/bpy_rna_driver.c index b4c0de51c04..1135ba121e3 100644 --- a/source/blender/python/intern/bpy_rna_driver.c +++ b/source/blender/python/intern/bpy_rna_driver.c @@ -63,7 +63,15 @@ PyObject *pyrna_driver_get_variable_value( } else { /* object & property */ - driver_arg = pyrna_prop_to_py(&ptr, prop); + PropertyType type = RNA_property_type(prop); + if (type == PROP_ENUM) { + /* Note that enum's are converted to strings by default, + * we want to avoid that, see: T52213 */ + driver_arg = PyLong_FromLong(RNA_property_enum_get(&ptr, prop)); + } + else { + driver_arg = pyrna_prop_to_py(&ptr, prop); + } } } else { diff --git a/source/blender/python/intern/gpu_offscreen.c b/source/blender/python/intern/gpu_offscreen.c index c7350ad2e3f..1fb866b70b7 100644 --- a/source/blender/python/intern/gpu_offscreen.c +++ b/source/blender/python/intern/gpu_offscreen.c @@ -147,7 +147,7 @@ static PyObject *pygpu_offscreen_unbind(BPy_GPUOffScreen *self, PyObject *args, /** * Use with PyArg_ParseTuple's "O&" formatting. */ -static int pygpu_offscreen_check_matrix(PyObject *o, void *p) +static int UNUSED_FUNCTION(pygpu_offscreen_check_matrix)(PyObject *o, void *p) { MatrixObject **pymat_p = p; MatrixObject *pymat = (MatrixObject *)o; @@ -192,6 +192,8 @@ PyDoc_STRVAR(pygpu_offscreen_draw_view3d_doc, ); static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *args, PyObject *kwds) { + /* TODO: This doesn't work currently because of eval_ctx. */ +#if 0 static const char *kwlist[] = {"scene", "render_layer", "view3d", "region", "projection_matrix", "modelview_matrix", NULL}; MatrixObject *py_mat_modelview, *py_mat_projection; @@ -244,6 +246,10 @@ static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *a MEM_freeN(rv3d_mats); Py_RETURN_NONE; +#else + UNUSED_VARS(self, args, kwds); +#endif + return NULL; } PyDoc_STRVAR(pygpu_offscreen_free_doc, diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c index 1eb8644a9a6..2963951838b 100644 --- a/source/blender/python/mathutils/mathutils_bvhtree.c +++ b/source/blender/python/mathutils/mathutils_bvhtree.c @@ -1049,6 +1049,8 @@ static DerivedMesh *bvh_get_derived_mesh( const char *funcname, struct Scene *scene, Object *ob, bool use_deform, bool use_render, bool use_cage) { + /* TODO: This doesn't work currently because of eval_ctx. */ +#if 0 /* we only need minimum mesh data for topology and vertex locations */ CustomDataMask mask = CD_MASK_BAREMESH; @@ -1096,6 +1098,11 @@ static DerivedMesh *bvh_get_derived_mesh( } } } +#else + UNUSED_VARS(funcname, scene, ob, use_deform, use_render, use_cage); +#endif + + return NULL; } PyDoc_STRVAR(C_BVHTree_FromObject_doc, diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 3086c9d4fad..a4de7104071 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -189,5 +189,7 @@ struct RenderData *RE_engine_get_render_data(struct Render *re); void RE_bake_engine_set_engine_parameters( struct Render *re, struct Main *bmain, struct Depsgraph *graph, struct Scene *scene); +struct SceneLayer *RE_engine_get_scene_layer(struct Render *re); + #endif /* __RE_ENGINE_H__ */ diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 145186548e6..45fb33034b0 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -38,6 +38,7 @@ struct bMovieHandle; struct bNodeTree; struct Depsgraph; +struct EvaluationContext; struct Image; struct ImageFormatData; struct Main; @@ -369,6 +370,7 @@ void RE_DataBase_GetView(struct Render *re, float mat[4][4]); void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]); void RE_GetCameraModelMatrix(struct Render *re, struct Object *camera, float r_mat[4][4]); struct Scene *RE_GetScene(struct Render *re); +struct EvaluationContext *RE_GetEvalCtx(struct Render *re); bool RE_force_single_renderlayer(struct Scene *scene); bool RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override, struct ReportList *reports); diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index 2b5d0ca4e14..f296c117495 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -41,6 +41,8 @@ struct DerivedMesh; struct ImagePool; struct MTex; struct Scene; +struct SceneLayer; +struct Render; /* render_texture.c */ /* used by particle.c, effect.c, editmesh_modes.c and brush.c, returns 1 if rgb, 0 otherwise */ @@ -70,17 +72,20 @@ struct PointDensity; void RE_point_density_cache( struct Scene *scene, + struct SceneLayer *sl, struct PointDensity *pd, const bool use_render_params); void RE_point_density_minmax( struct Scene *scene, + struct SceneLayer *sl, struct PointDensity *pd, const bool use_render_params, float r_min[3], float r_max[3]); void RE_point_density_sample( struct Scene *scene, + struct SceneLayer *sl, struct PointDensity *pd, const int resolution, const bool use_render_params, diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h index 13f16ce0bd7..3ef6e9d7476 100644 --- a/source/blender/render/intern/include/shading.h +++ b/source/blender/render/intern/include/shading.h @@ -57,7 +57,7 @@ typedef struct ShadeSample { void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr); void shade_input_set_triangle_i(struct ShadeInput *shi, struct ObjectInstanceRen *obi, struct VlakRen *vlr, short i1, short i2, short i3); -void shade_input_set_triangle(struct ShadeInput *shi, volatile int obi, volatile int facenr, int normal_flip); +void shade_input_set_triangle(struct ShadeInput *shi, int obi, int facenr, int normal_flip); void shade_input_copy_triangle(struct ShadeInput *shi, struct ShadeInput *from); void shade_input_calc_viewco(struct ShadeInput *shi, float x, float y, float z, float view[3], float dxyview[2], float co[3], float dxco[3], float dyco[3]); void shade_input_set_viewco(struct ShadeInput *shi, float x, float y, float sx, float sy, float z); diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index 81e41a20f2e..103fa3e6034 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -59,6 +59,7 @@ static void rtbuild_init(RTBuilder *b) b->primitives.begin = NULL; b->primitives.end = NULL; b->primitives.maxsize = 0; + b->depth = 0; for (int i = 0; i < RTBUILD_MAX_CHILDS; i++) b->child_offset[i] = 0; @@ -178,6 +179,8 @@ RTBuilder *rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp) { rtbuild_init(tmp); + tmp->depth = b->depth + 1; + for (int i = 0; i < 3; i++) if (b->sorted_begin[i]) { tmp->sorted_begin[i] = b->sorted_begin[i] + b->child_offset[child]; @@ -336,6 +339,15 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) int baxis = -1, boffset = 0; if (size > nchilds) { + if (b->depth > RTBUILD_MAX_SAH_DEPTH) { + // for degenerate cases we avoid running out of stack space + // by simply splitting the children in the middle + b->child_offset[0] = 0; + b->child_offset[1] = (size+1)/2; + b->child_offset[2] = size; + return 2; + } + float bcost = FLT_MAX; baxis = -1; boffset = size / 2; diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.h b/source/blender/render/intern/raytrace/rayobject_rtbuild.h index 9e296da144b..83042ef3d7e 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.h +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.h @@ -49,7 +49,8 @@ extern "C" { * generate with simple calls, and then convert to the theirs * specific structure on the fly. */ -#define RTBUILD_MAX_CHILDS 32 +#define RTBUILD_MAX_CHILDS 32 +#define RTBUILD_MAX_SAH_DEPTH 256 typedef struct RTBuilder { @@ -79,6 +80,8 @@ typedef struct RTBuilder { float bb[6]; + /* current depth */ + int depth; } RTBuilder; /* used during creation */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 42cef07205c..9d2ac76f7e6 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1350,10 +1350,11 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if (!(psmd->modifier.mode & eModifierMode_Render)) return 0; - sim.scene= re->scene; - sim.ob= ob; - sim.psys= psys; - sim.psmd= psmd; + sim.eval_ctx = re->eval_ctx; + sim.scene = re->scene; + sim.ob = ob; + sim.psys = psys; + sim.psmd = psmd; if (part->phystype==PART_PHYS_KEYED) psys_count_keyed_targets(&sim); @@ -2600,13 +2601,13 @@ static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset) if (ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1; - BKE_displist_make_surf(re->scene, ob, &displist, &dm, 1, 0, 1); + BKE_displist_make_surf(re->eval_ctx, re->scene, ob, &displist, &dm, 1, 0, 1); if (dm) { if (need_orco) { orco = get_object_orco(re, ob); if (!orco) { - orco= BKE_displist_make_orco(re->scene, ob, dm, true, true); + orco= BKE_displist_make_orco(re->eval_ctx, re->scene, ob, dm, true, true); if (orco) { set_object_orco(re, ob, orco); } @@ -2658,7 +2659,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) if (ob->type==OB_FONT && cu->str==NULL) return; else if (ob->type==OB_CURVE && cu->nurb.first==NULL) return; - BKE_displist_make_curveTypes_forRender(re->scene, ob, &disp, &dm, false, true); + BKE_displist_make_curveTypes_forRender(re->eval_ctx, re->scene, ob, &disp, &dm, false, true); dl= disp.first; if (dl==NULL) return; @@ -2685,7 +2686,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) if (need_orco) { orco = get_object_orco(re, ob); if (!orco) { - orco = BKE_displist_make_orco(re->scene, ob, dm, true, true); + orco = BKE_displist_make_orco(re->eval_ctx, re->scene, ob, dm, true, true); if (orco) { set_object_orco(re, ob, orco); } @@ -2699,7 +2700,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) if (need_orco) { orco = get_object_orco(re, ob); if (!orco) { - orco = BKE_curve_make_orco(re->scene, ob, NULL); + orco = BKE_curve_make_orco(re->eval_ctx, re->scene, ob, NULL); set_object_orco(re, ob, orco); } } @@ -3199,9 +3200,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) #endif if (re->r.scemode & R_VIEWPORT_PREVIEW) - dm= mesh_create_derived_view(re->scene, ob, mask); + dm= mesh_create_derived_view(re->eval_ctx, re->scene, ob, mask); else - dm= mesh_create_derived_render(re->scene, ob, mask); + dm= mesh_create_derived_render(re->eval_ctx, re->scene, ob, mask); if (dm==NULL) return; /* in case duplicated object fails? */ mvert= dm->getVertArray(dm); @@ -4619,9 +4620,9 @@ static void init_render_object_data(Render *re, ObjectRen *obr, int timeoffset) const CustomDataMask mask = CD_MASK_RENDER_INTERNAL; if (re->r.scemode & R_VIEWPORT_PREVIEW) - dm = mesh_create_derived_view(re->scene, ob, mask); + dm = mesh_create_derived_view(re->eval_ctx, re->scene, ob, mask); else - dm = mesh_create_derived_render(re->scene, ob, mask); + dm = mesh_create_derived_render(re->eval_ctx, re->scene, ob, mask); dm->release(dm); } @@ -4930,7 +4931,7 @@ static void dupli_render_particle_set(Render *re, Object *ob, int timeoffset, in /* 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(re->scene, ob, CD_MASK_RENDER_INTERNAL); + dm = mesh_create_derived_render(re->eval_ctx, re->scene, ob, CD_MASK_RENDER_INTERNAL); dm->release(dm); for (psys=ob->particlesystem.first; psys; psys=psys->next) @@ -5053,7 +5054,7 @@ static void database_init_objects(Render *re, unsigned int UNUSED(renderlay), in * system need to have render settings set for dupli particles */ dupli_render_particle_set(re, ob, timeoffset, 0, 1); duplilist = object_duplilist(re->eval_ctx, re->scene, ob); - duplilist_apply_data = duplilist_apply(ob, NULL, duplilist); + duplilist_apply_data = duplilist_apply(re->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. */ diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index be6d6459b2f..c2e6d540ad8 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -791,3 +791,8 @@ void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, s } } } + +SceneLayer *RE_engine_get_scene_layer(Render *re) +{ + return re->eval_ctx->scene_layer; +} diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 7219630f519..c13583139ae 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -354,6 +354,15 @@ Scene *RE_GetScene(Render *re) return NULL; } +EvaluationContext *RE_GetEvalCtx(Render *re) +{ + if (re) { + return re->eval_ctx; + } + + return NULL; +} + /** * Same as #RE_AcquireResultImage but creating the necessary views to store the result * fill provided result struct with a copy of thew views of what is done so far the @@ -3796,8 +3805,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) { Object *camera; - /* TODO(sergey): Get proper scene layer here. */ - SceneLayer *scene_layer = BKE_scene_layer_context_active_ex_PLACEHOLDER(bmain, sce); + SceneLayer *scene_layer = BKE_scene_layer_from_scene_get(sce); int winx, winy; winx = (sce->r.size * sce->r.xsch) / 100; @@ -3812,6 +3820,7 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) re->scene_color_manage = BKE_scene_check_color_management_enabled(sce); re->lay = sce->lay; re->depsgraph = BKE_scene_get_depsgraph(sce, scene_layer); + re->eval_ctx->scene_layer = scene_layer; camera = RE_GetCamera(re); RE_SetCamera(re, camera); diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index fb047aad897..63fe7e4471a 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -58,6 +58,8 @@ #include "BKE_texture.h" #include "BKE_colortools.h" +#include "DEG_depsgraph.h" + #include "render_types.h" #include "texture.h" #include "pointdensity.h" @@ -167,7 +169,7 @@ static void alloc_point_data(PointDensity *pd) } } -static void pointdensity_cache_psys(Scene *scene, +static void pointdensity_cache_psys(EvaluationContext *eval_ctx, Scene *scene, PointDensity *pd, Object *ob, ParticleSystem *psys, @@ -201,12 +203,12 @@ static void pointdensity_cache_psys(Scene *scene, } if (use_render_params) { - dm = mesh_create_derived_render(scene, + dm = mesh_create_derived_render(eval_ctx, scene, ob, CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL); } else { - dm = mesh_get_derived_final(scene, + dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL); } @@ -216,6 +218,7 @@ static void pointdensity_cache_psys(Scene *scene, return; } + sim.eval_ctx = eval_ctx; sim.scene = scene; sim.ob = ob; sim.psys = psys; @@ -400,7 +403,7 @@ static void pointdensity_cache_vertex_normal(PointDensity *pd, Object *UNUSED(ob } } -static void pointdensity_cache_object(Scene *scene, +static void pointdensity_cache_object(EvaluationContext *eval_ctx, Scene *scene, PointDensity *pd, Object *ob, const bool use_render_params) @@ -421,10 +424,10 @@ static void pointdensity_cache_object(Scene *scene, } if (use_render_params) { - dm = mesh_create_derived_render(scene, ob, mask); + dm = mesh_create_derived_render(eval_ctx, scene, ob, mask); } else { - dm = mesh_get_derived_final(scene, ob, mask); + dm = mesh_get_derived_final(eval_ctx, scene, ob, mask); } mvert = dm->getVertArray(dm); /* local object space */ @@ -475,7 +478,7 @@ static void pointdensity_cache_object(Scene *scene, } -static void cache_pointdensity_ex(Scene *scene, +static void cache_pointdensity_ex(EvaluationContext *eval_ctx, Scene *scene, PointDensity *pd, float viewmat[4][4], float winmat[4][4], @@ -504,7 +507,8 @@ static void cache_pointdensity_ex(Scene *scene, return; } - pointdensity_cache_psys(scene, + pointdensity_cache_psys(eval_ctx, + scene, pd, ob, psys, @@ -515,13 +519,14 @@ static void cache_pointdensity_ex(Scene *scene, else if (pd->source == TEX_PD_OBJECT) { Object *ob = pd->object; if (ob && ob->type == OB_MESH) - pointdensity_cache_object(scene, pd, ob, use_render_params); + pointdensity_cache_object(eval_ctx, scene, pd, ob, use_render_params); } } void cache_pointdensity(Render *re, PointDensity *pd) { - cache_pointdensity_ex(re->scene, + cache_pointdensity_ex(re->eval_ctx, + re->scene, pd, re->viewmat, re->winmat, re->winx, re->winy, @@ -876,7 +881,8 @@ static void sample_dummy_point_density(int resolution, float *values) memset(values, 0, sizeof(float) * 4 * resolution * resolution * resolution); } -static void particle_system_minmax(Scene *scene, +static void particle_system_minmax(EvaluationContext *eval_ctx, + Scene *scene, Object *object, ParticleSystem *psys, float radius, @@ -903,6 +909,7 @@ static void particle_system_minmax(Scene *scene, psys_render_set(object, psys, mat, mat, 1, 1, 0); } + sim.eval_ctx = eval_ctx; sim.scene = scene; sim.ob = object; sim.psys = psys; @@ -938,19 +945,28 @@ static void particle_system_minmax(Scene *scene, void RE_point_density_cache( Scene *scene, + SceneLayer *sl, PointDensity *pd, const bool use_render_params) { + EvaluationContext eval_ctx = {0}; float mat[4][4]; + + DEG_evaluation_context_init(&eval_ctx, use_render_params ? DAG_EVAL_RENDER + : DAG_EVAL_VIEWPORT); + + eval_ctx.scene_layer = sl; + /* Same matricies/resolution as dupli_render_particle_set(). */ unit_m4(mat); BLI_mutex_lock(&sample_mutex); - cache_pointdensity_ex(scene, pd, mat, mat, 1, 1, use_render_params); + cache_pointdensity_ex(&eval_ctx, scene, pd, mat, mat, 1, 1, use_render_params); BLI_mutex_unlock(&sample_mutex); } void RE_point_density_minmax( struct Scene *scene, + SceneLayer *sl, struct PointDensity *pd, const bool use_render_params, float r_min[3], float r_max[3]) @@ -963,6 +979,8 @@ void RE_point_density_minmax( } if (pd->source == TEX_PD_PSYS) { ParticleSystem *psys; + EvaluationContext eval_ctx = {0}; + if (pd->psys == 0) { zero_v3(r_min); zero_v3(r_max); @@ -974,7 +992,15 @@ void RE_point_density_minmax( zero_v3(r_max); return; } - particle_system_minmax(scene, + + DEG_evaluation_context_init(&eval_ctx, use_render_params ? DAG_EVAL_RENDER : + DAG_EVAL_VIEWPORT); + + eval_ctx.ctime = (float)scene->r.cfra + scene->r.subframe; + eval_ctx.scene_layer = sl; + + particle_system_minmax(&eval_ctx, + scene, object, psys, pd->radius, @@ -1044,6 +1070,7 @@ static void point_density_sample_func(void *data_v, const int iter) */ void RE_point_density_sample( Scene *scene, + SceneLayer *sl, PointDensity *pd, const int resolution, const bool use_render_params, @@ -1063,6 +1090,7 @@ void RE_point_density_sample( BLI_mutex_lock(&sample_mutex); RE_point_density_minmax(scene, + sl, pd, use_render_params, min, diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 597a2338fe7..660b82b884d 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -292,12 +292,8 @@ void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen } } -/* note, facenr declared volatile due to over-eager -O2 optimization's - * on cygwin (particularly -frerun-cse-after-loop) - */ - /* copy data from face to ShadeInput, scanline case */ -void shade_input_set_triangle(ShadeInput *shi, volatile int obi, volatile int facenr, int UNUSED(normal_flip)) +void shade_input_set_triangle(ShadeInput *shi, int obi, int facenr, int UNUSED(normal_flip)) { if (facenr > 0) { shi->obi = &R.objectinstance[obi]; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index a8c67a296af..6e5f11c3062 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -42,9 +42,6 @@ #include "WM_keymap.h" #include "BLI_compiler_attrs.h" -/* Include external manipulator API's */ -#include "manipulators/WM_manipulator_api.h" - #ifdef __cplusplus extern "C" { #endif @@ -68,6 +65,7 @@ struct ImBuf; struct ImageFormatData; struct ARegion; struct ScrArea; +struct Main; #ifdef WITH_INPUT_NDOF struct wmNDOFMotionData; @@ -165,6 +163,7 @@ float WM_cursor_pressure (const struct wmWindow *win); /* event map */ int WM_userdef_event_map(int kmitype); +int WM_userdef_event_type_from_keymap_type(int kmitype); /* handlers */ @@ -212,8 +211,9 @@ struct wmEventHandler *WM_event_add_dropbox_handler(ListBase *handlers, ListBase /* mouse */ void WM_event_add_mousemove(struct bContext *C); -bool WM_modal_tweak_exit(const struct wmEvent *event, int tweak_event); +bool WM_event_is_modal_tweak_exit(const struct wmEvent *event, int tweak_event); bool WM_event_is_absolute(const struct wmEvent *event); +bool WM_event_is_last_mousemove(const struct wmEvent *event); #ifdef WITH_INPUT_NDOF /* 3D mouse */ diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 02601cbbcea..bb7384a64c1 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -121,6 +121,9 @@ struct ImBuf; #include "wm_event_types.h" #include "manipulators/WM_manipulator_types.h" +/* Include external manipulator API's */ +#include "manipulators/WM_manipulator_api.h" + /* ************** wmOperatorType ************************ */ /* flag */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 6a1be832918..244f833e6b3 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -335,7 +335,7 @@ void wm_event_do_notifiers(bContext *C) } } if (ELEM(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_WM)) { - SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene); + SceneLayer *sl = CTX_data_scene_layer(C); ED_info_stats_clear(sl); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO, NULL); } @@ -644,6 +644,16 @@ bool WM_event_is_absolute(const wmEvent *event) return (event->tablet_data != NULL); } +bool WM_event_is_last_mousemove(const wmEvent *event) +{ + while ((event = event->next)) { + if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { + return false; + } + } + return true; +} + #ifdef WITH_INPUT_NDOF void WM_ndof_deadzone_set(float deadzone) { @@ -1108,6 +1118,9 @@ bool WM_operator_last_properties_store(wmOperator *UNUSED(op)) #endif +/** + * Also used for exec when 'event' is NULL. + */ static int wm_operator_invoke( bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties, ReportList *reports, const bool poll_only) @@ -1123,7 +1136,9 @@ static int wm_operator_invoke( wmOperator *op = wm_operator_create(wm, ot, properties, reports); /* if reports == NULL, they'll be initialized */ const bool is_nested_call = (wm->op_undo_depth != 0); - op->flag |= OP_IS_INVOKE; + if (event != NULL) { + op->flag |= OP_IS_INVOKE; + } /* initialize setting from previous run */ if (!is_nested_call) { /* not called by py script */ @@ -1574,6 +1589,36 @@ int WM_userdef_event_map(int kmitype) return kmitype; } +/** + * Use so we can check if 'wmEvent.type' is released in modal operators. + * + * An alternative would be to add a 'wmEvent.type_nokeymap'... or similar. + */ +int WM_userdef_event_type_from_keymap_type(int kmitype) +{ + switch (kmitype) { + case SELECTMOUSE: + return (U.flag & USER_LMOUSESELECT) ? LEFTMOUSE : RIGHTMOUSE; + case ACTIONMOUSE: + return (U.flag & USER_LMOUSESELECT) ? RIGHTMOUSE : LEFTMOUSE; + case EVT_TWEAK_S: + return (U.flag & USER_LMOUSESELECT) ? LEFTMOUSE : RIGHTMOUSE; + case EVT_TWEAK_A: + return (U.flag & USER_LMOUSESELECT) ? RIGHTMOUSE : LEFTMOUSE; + case EVT_TWEAK_L: + return LEFTMOUSE; + case EVT_TWEAK_M: + return MIDDLEMOUSE; + case EVT_TWEAK_R: + return RIGHTMOUSE; + case WHEELOUTMOUSE: + return (U.uiflag & USER_WHEELZOOMDIR) ? WHEELUPMOUSE : WHEELDOWNMOUSE; + case WHEELINMOUSE: + return (U.uiflag & USER_WHEELZOOMDIR) ? WHEELDOWNMOUSE : WHEELUPMOUSE; + } + + return kmitype; +} static int wm_eventmatch(const wmEvent *winevent, wmKeyMapItem *kmi) { @@ -2152,54 +2197,120 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers wmManipulatorMap *mmap = handler->manipulator_map; wmManipulator *mpr = wm_manipulatormap_highlight_get(mmap); + if (region->manipulator_map != handler->manipulator_map) { + WM_manipulatormap_tag_refresh(handler->manipulator_map); + } + wm_manipulatormap_handler_context(C, handler); wm_region_mouse_co(C, event); /* handle manipulator highlighting */ - if (event->type == MOUSEMOVE && !wm_manipulatormap_active_get(mmap)) { + if (event->type == MOUSEMOVE && !wm_manipulatormap_modal_get(mmap)) { int part; mpr = wm_manipulatormap_highlight_find(mmap, C, event, &part); wm_manipulatormap_highlight_set(mmap, C, mpr, part); } /* handle user configurable manipulator-map keymap */ - else if (mpr) { - /* get user customized keymap from default one */ - const wmManipulatorGroup *highlightgroup = mpr->parent_mgroup; - const wmKeyMap *keymap = WM_keymap_active(wm, highlightgroup->type->keymap); - wmKeyMapItem *kmi; - - PRINT("%s: checking '%s' ...", __func__, keymap->idname); - - if (!keymap->poll || keymap->poll(C)) { - PRINT("pass\n"); - for (kmi = keymap->items.first; kmi; kmi = kmi->next) { - if (wm_eventmatch(event, kmi)) { - wmOperator *op = handler->op; - - PRINT("%s: item matched '%s'\n", __func__, kmi->idname); - - /* weak, but allows interactive callback to not use rawkey */ - event->keymap_idname = kmi->idname; - - /* handler->op is called later, we want keymap op to be triggered here */ - handler->op = NULL; - action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr); - handler->op = op; - - if (action & WM_HANDLER_BREAK) { - if (action & WM_HANDLER_HANDLED) { - if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) - printf("%s: handled - and pass on! '%s'\n", __func__, kmi->idname); + else { + /* Either we operate on a single highlighted item + * or groups attached to the selected manipulators. + * To simplify things both cases loop over an array of items. */ + wmManipulatorGroup *mgroup_first; + bool is_mgroup_single; + + if (ISMOUSE(event->type)) { + /* Keep mpr set as-is, just fake single selection. */ + if (mpr) { + mgroup_first = mpr->parent_mgroup; + } + else { + mgroup_first = NULL; + } + is_mgroup_single = true; + } + else { + if (WM_manipulatormap_is_any_selected(mmap)) { + const ListBase *groups = WM_manipulatormap_group_list(mmap); + mgroup_first = groups->first; + } + else { + mgroup_first = NULL; + } + is_mgroup_single = false; + } + + /* Don't use from now on. */ + mpr = NULL; + + for (wmManipulatorGroup *mgroup = mgroup_first; mgroup; mgroup = mgroup->next) { + /* get user customized keymap from default one */ + + if ((is_mgroup_single == false) && + /* We might want to change the logic here and use some kind of manipulator edit-mode. + * For now just use keymap when a selection exists. */ + wm_manipulatorgroup_is_any_selected(mgroup) == false) + { + continue; + } + + const wmKeyMap *keymap = WM_keymap_active(wm, mgroup->type->keymap); + wmKeyMapItem *kmi; + + PRINT("%s: checking '%s' ...", __func__, keymap->idname); + + if (!keymap->poll || keymap->poll(C)) { + PRINT("pass\n"); + for (kmi = keymap->items.first; kmi; kmi = kmi->next) { + if (wm_eventmatch(event, kmi)) { + wmOperator *op = handler->op; + + PRINT("%s: item matched '%s'\n", __func__, kmi->idname); + + /* weak, but allows interactive callback to not use rawkey */ + event->keymap_idname = kmi->idname; + + CTX_wm_manipulator_group_set(C, mgroup); + + /* handler->op is called later, we want keymap op to be triggered here */ + handler->op = NULL; + action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr); + handler->op = op; + + CTX_wm_manipulator_group_set(C, NULL); + + if (action & WM_HANDLER_BREAK) { + if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) { + printf("%s: handled - and pass on! '%s'\n", + __func__, kmi->idname); + } + break; } else { - PRINT("%s: un-handled '%s'\n", __func__, kmi->idname); + if (action & WM_HANDLER_HANDLED) { + if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) { + printf("%s: handled - and pass on! '%s'\n", + __func__, kmi->idname); + } + } + else { + PRINT("%s: un-handled '%s'\n", + __func__, kmi->idname); + } } } } } - } - else { - PRINT("fail\n"); + else { + PRINT("fail\n"); + } + + if (action & WM_HANDLER_BREAK) { + break; + } + + if (is_mgroup_single) { + break; + } } } @@ -2701,7 +2812,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op) wmWindow *win = CTX_wm_window(C); /* only allow 1 file selector open per window */ - for (handler = win->handlers.first; handler; handler = handlernext) { + for (handler = win->modalhandlers.first; handler; handler = handlernext) { handlernext = handler->next; if (handler->type == WM_HANDLER_FILESELECT) { @@ -2715,7 +2826,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op) if (sfile->op == handler->op) { CTX_wm_area_set(C, sa); - wm_handler_fileselect_do(C, &win->handlers, handler, EVT_FILESELECT_CANCEL); + wm_handler_fileselect_do(C, &win->modalhandlers, handler, EVT_FILESELECT_CANCEL); break; } } @@ -2723,7 +2834,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op) /* if not found we stop the handler without changing the screen */ if (!sa) - wm_handler_fileselect_do(C, &win->handlers, handler, EVT_FILESELECT_EXTERNAL_CANCEL); + wm_handler_fileselect_do(C, &win->modalhandlers, handler, EVT_FILESELECT_EXTERNAL_CANCEL); } } @@ -2734,7 +2845,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op) handler->op_area = CTX_wm_area(C); handler->op_region = CTX_wm_region(C); - BLI_addhead(&win->handlers, handler); + BLI_addhead(&win->modalhandlers, handler); /* check props once before invoking if check is available * ensures initial properties are valid */ @@ -2784,7 +2895,8 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op) void WM_event_modal_handler_area_replace(wmWindow *win, const ScrArea *old_area, ScrArea *new_area) { for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) { - if (handler->op_area == old_area) { + /* fileselect handler is quite special... it needs to keep old area stored in handler, so don't change it */ + if ((handler->op_area == old_area) && (handler->type != WM_HANDLER_FILESELECT)) { handler->op_area = new_area; } } @@ -2986,7 +3098,7 @@ void WM_event_add_mousemove(bContext *C) /* for modal callbacks, check configuration for how to interpret exit with tweaks */ -bool WM_modal_tweak_exit(const wmEvent *event, int tweak_event) +bool WM_event_is_modal_tweak_exit(const wmEvent *event, int tweak_event) { /* if the release-confirm userpref setting is enabled, * tweak events can be canceled when mouse is released diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 5631a0108fd..cedf50a3035 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -983,7 +983,7 @@ static void wm_history_file_update(void) /* screen can be NULL */ -static ImBuf *blend_file_thumb(Scene *scene, SceneLayer *sl, bScreen *screen, BlendThumbnail **thumb_pt) +static ImBuf *blend_file_thumb(const bContext *C, Scene *scene, SceneLayer *sl, bScreen *screen, BlendThumbnail **thumb_pt) { /* will be scaled down, but gives some nice oversampling */ ImBuf *ibuf; @@ -995,6 +995,10 @@ static ImBuf *blend_file_thumb(Scene *scene, SceneLayer *sl, bScreen *screen, Bl ARegion *ar = NULL; View3D *v3d = NULL; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); + /* In case we are given a valid thumbnail data, just generate image from it. */ if (*thumb_pt) { thumb = *thumb_pt; @@ -1020,14 +1024,14 @@ static ImBuf *blend_file_thumb(Scene *scene, SceneLayer *sl, bScreen *screen, Bl /* gets scaled to BLEN_THUMB_SIZE */ if (scene->camera) { ibuf = ED_view3d_draw_offscreen_imbuf_simple( - scene, sl, scene->camera, + &eval_ctx, scene, sl, scene->camera, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, IB_rect, OB_SOLID, false, false, false, R_ALPHAPREMUL, 0, false, NULL, NULL, NULL, err_out); } else { ibuf = ED_view3d_draw_offscreen_imbuf( - scene, sl, v3d, ar, + &eval_ctx, scene, sl, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, IB_rect, false, R_ALPHAPREMUL, 0, false, NULL, NULL, NULL, err_out); @@ -1123,7 +1127,7 @@ static int wm_file_write(bContext *C, const char *filepath, int fileflags, Repor /* Main now can store a .blend thumbnail, usefull for background mode or thumbnail customization. */ main_thumb = thumb = CTX_data_main(C)->blen_thumb; if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) { - ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_data_scene_layer(C), CTX_wm_screen(C), &thumb); + ibuf_thumb = blend_file_thumb(C, CTX_data_scene(C), CTX_data_scene_layer(C), CTX_wm_screen(C), &thumb); } /* operator now handles overwrite checks */ diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index a96ddb7368a..ec248c28f0f 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -173,6 +173,7 @@ void WM_init(bContext *C, int argc, const char **argv) BKE_library_callback_free_window_manager_set(wm_close_and_free); /* library.c */ BKE_library_callback_free_notifier_reference_set(WM_main_remove_notifier_reference); /* library.c */ BKE_region_callback_free_manipulatormap_set(wm_manipulatormap_remove); /* screen.c */ + BKE_region_callback_refresh_tag_manipulatormap_set(WM_manipulatormap_tag_refresh); BKE_library_callback_remap_editor_id_reference_set(WM_main_remap_editor_id_reference); /* library.c */ BKE_blender_callback_test_break_set(wm_window_testbreak); /* blender.c */ BKE_spacedata_callback_id_remap_set(ED_spacedata_id_remap); /* screen.c */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5001fc7817f..eeab9309a59 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -809,9 +809,19 @@ static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, Propert } \ } (void)0 +#define CTX_TEST_SPACE_TYPE(space_data_type, member_full, dataptr_cmp) \ + { \ + const char *ctx_member_full = member_full; \ + if (space_data->spacetype == space_data_type && ptr->data == dataptr_cmp) { \ + member_id = ctx_member_full; \ + break; \ + } \ + } (void)0 + switch (GS(((ID *)ptr->id.data)->name)) { case ID_SCE: { + CTX_TEST_PTR_DATA_TYPE(C, "active_gpencil_brush", RNA_GPencilBrush, ptr, CTX_data_active_gpencil_brush(C)); CTX_TEST_PTR_ID(C, "scene", ptr->id.data); break; } @@ -846,10 +856,18 @@ static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, Propert { CTX_TEST_PTR_ID(C, "screen", ptr->id.data); - CTX_TEST_PTR_DATA_TYPE(C, "space_data", RNA_Space, ptr, CTX_wm_space_data(C)); + SpaceLink *space_data = CTX_wm_space_data(C); + + CTX_TEST_PTR_DATA_TYPE(C, "space_data", RNA_Space, ptr, space_data); CTX_TEST_PTR_DATA_TYPE(C, "area", RNA_Area, ptr, CTX_wm_area(C)); CTX_TEST_PTR_DATA_TYPE(C, "region", RNA_Region, ptr, CTX_wm_region(C)); + CTX_TEST_SPACE_TYPE(SPACE_IMAGE, "space_data.uv_editor", space_data); + CTX_TEST_SPACE_TYPE(SPACE_VIEW3D, "space_data.fx_settings", &(CTX_wm_view3d(C)->fx_settings)); + CTX_TEST_SPACE_TYPE(SPACE_NLA, "space_data.dopesheet", CTX_wm_space_nla(C)->ads); + CTX_TEST_SPACE_TYPE(SPACE_IPO, "space_data.dopesheet", CTX_wm_space_graph(C)->ads); + CTX_TEST_SPACE_TYPE(SPACE_ACTION, "space_data.dopesheet", &(CTX_wm_space_action(C)->ads)); + CTX_TEST_SPACE_TYPE(SPACE_FILE, "space_data.params", CTX_wm_space_file(C)->params); break; } } @@ -863,6 +881,7 @@ static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, Propert } #undef CTX_TEST_PTR_ID #undef CTX_TEST_PTR_ID_CAST +#undef CTX_TEST_SPACE_TYPE } return ret; diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 8068b048d10..595ccc94584 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -418,6 +418,11 @@ void WM_window_set_dpi(wmWindow *win) { int auto_dpi = GHOST_GetDPIHint(win->ghostwin); + /* Clamp auto DPI to 96, since our font/interface drawing does not work well + * with lower sizes. The main case we are interested in supporting is higher + * DPI. If a smaller UI is desired it is still possible to adjust UI scale. */ + auto_dpi = MAX2(auto_dpi, 96); + /* Lazily init UI scale size, preserving backwards compatibility by * computing UI scale from ratio of previous DPI and auto DPI */ if (U.ui_scale == 0) { diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_api.h b/source/blender/windowmanager/manipulators/WM_manipulator_api.h index d6774333ba4..a29e31985a0 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_api.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_api.h @@ -59,16 +59,20 @@ struct wmManipulatorMapType_Params; struct wmManipulator *WM_manipulator_new_ptr( const struct wmManipulatorType *wt, struct wmManipulatorGroup *mgroup, - const char *name, struct PointerRNA *properties); + struct PointerRNA *properties); struct wmManipulator *WM_manipulator_new( const char *idname, struct wmManipulatorGroup *mgroup, - const char *name, struct PointerRNA *properties); -void WM_manipulator_free( + struct PointerRNA *properties); +void WM_manipulator_free(struct wmManipulator *mpr); +void WM_manipulator_unlink( ListBase *manipulatorlist, struct wmManipulatorMap *mmap, struct wmManipulator *mpr, struct bContext *C); void WM_manipulator_name_set(struct wmManipulatorGroup *mgroup, struct wmManipulator *mpr, const char *name); +bool WM_manipulator_select_unlink(struct wmManipulatorMap *mmap, struct wmManipulator *mpr); +bool WM_manipulator_select_set(struct wmManipulatorMap *mmap, struct wmManipulator *mpr, bool select); + struct PointerRNA *WM_manipulator_set_operator( struct wmManipulator *, struct wmOperatorType *ot, struct IDProperty *properties); @@ -113,8 +117,8 @@ void WM_manipulator_properties_free(struct PointerRNA *ptr); const struct wmManipulatorType *WM_manipulatortype_find(const char *idname, bool quiet); void WM_manipulatortype_append(void (*wtfunc)(struct wmManipulatorType *)); void WM_manipulatortype_append_ptr(void (*mnpfunc)(struct wmManipulatorType *, void *), void *userdata); -bool WM_manipulatortype_remove(const char *idname); -void WM_manipulatortype_remove_ptr(struct wmManipulatorType *wt); +bool WM_manipulatortype_remove(struct bContext *C, struct Main *bmain, const char *idname); +void WM_manipulatortype_remove_ptr(struct bContext *C, struct Main *bmain, struct wmManipulatorType *wt); void WM_manipulatortype_iter(struct GHashIterator *ghi); /* wm_manipulator_group_type.c */ @@ -174,10 +178,13 @@ void WM_manipulator_target_property_value_set_array( struct bContext *C, const struct wmManipulator *mpr, struct wmManipulatorProperty *mpr_prop, const float *value); -void WM_manipulator_target_property_range_get( +bool WM_manipulator_target_property_range_get( const struct wmManipulator *mpr, struct wmManipulatorProperty *mpr_prop, float range[2]); +int WM_manipulator_target_property_array_length( + const struct wmManipulator *mpr, struct wmManipulatorProperty *mpr_prop); + /* definitions */ const struct wmManipulatorPropertyType *WM_manipulatortype_target_property_find( const struct wmManipulatorType *wt, const char *idname); @@ -202,10 +209,15 @@ struct wmManipulatorMap *WM_manipulatormap_new_from_type( const struct wmManipulatorMapType_Params *mmap_params); const struct ListBase *WM_manipulatormap_group_list(struct wmManipulatorMap *mmap); void WM_manipulatormap_tag_refresh(struct wmManipulatorMap *mmap); -void WM_manipulatormap_draw(struct wmManipulatorMap *mmap, const struct bContext *C, const int drawstep); +void WM_manipulatormap_draw( + struct wmManipulatorMap *mmap, const struct bContext *C, const eWM_ManipulatorMapDrawStep drawstep); void WM_manipulatormap_add_handlers(struct ARegion *ar, struct wmManipulatorMap *mmap); bool WM_manipulatormap_select_all(struct bContext *C, struct wmManipulatorMap *mmap, const int action); bool WM_manipulatormap_cursor_set(const struct wmManipulatorMap *mmap, struct wmWindow *win); +bool WM_manipulatormap_is_any_selected(const struct wmManipulatorMap *mmap); +bool WM_manipulatormap_minmax( + const struct wmManipulatorMap *mmap, bool use_hidden, bool use_select, + float r_min[3], float r_max[3]); /* -------------------------------------------------------------------- */ /* wmManipulatorMapType */ @@ -228,6 +240,9 @@ struct wmManipulatorGroupTypeRef *WM_manipulatormaptype_group_link_ptr( struct wmManipulatorMapType *mmap_type, struct wmManipulatorGroupType *wgt); +void WM_manipulatormaptype_group_init_runtime_keymap( + const struct Main *bmain, + struct wmManipulatorGroupType *wgt); void WM_manipulatormaptype_group_init_runtime( const struct Main *bmain, struct wmManipulatorMapType *mmap_type, struct wmManipulatorGroupType *wgt); @@ -238,7 +253,9 @@ void WM_manipulatormaptype_group_unlink( void WM_manipulatormaptype_group_free(struct wmManipulatorGroupTypeRef *wgt); /* -------------------------------------------------------------------- */ -/* Manipulator Add/Remove (High level API) */ +/* ManipulatorGroup */ + +/* Add/Remove (High level API) */ void WM_manipulator_group_add_ptr_ex( struct wmManipulatorGroupType *wgt, @@ -261,4 +278,7 @@ void WM_manipulator_group_remove_ptr_delayed( struct wmManipulatorGroupType *wgt); void WM_manipulator_group_remove_delayed(const char *idname); +/* Utilities */ +void WM_manipulator_group_is_any_selected(const char *idname); + #endif /* __WM_MANIPULATOR_API_H__ */ diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_types.h b/source/blender/windowmanager/manipulators/WM_manipulator_types.h index b1b6c5b1c0f..065206eb9b3 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_types.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h @@ -45,19 +45,90 @@ struct wmManipulator; struct wmManipulatorProperty; struct wmKeyConfig; -#include "wm_manipulator_fn.h" - #include "DNA_listBase.h" + +/* -------------------------------------------------------------------- */ +/* Enum Typedef's */ + + +/** + * #wmManipulator.state + */ +typedef enum eWM_ManipulatorState { + WM_MANIPULATOR_STATE_HIGHLIGHT = (1 << 0), /* while hovered */ + WM_MANIPULATOR_STATE_MODAL = (1 << 1), /* while dragging */ + WM_MANIPULATOR_STATE_SELECT = (1 << 2), +} eWM_ManipulatorState; + + +/** + * #wmManipulator.flag + * Flags for individual manipulators. + */ +typedef enum eWM_ManipulatorFlag { + WM_MANIPULATOR_DRAW_HOVER = (1 << 0), /* draw *only* while hovering */ + WM_MANIPULATOR_DRAW_MODAL = (1 << 1), /* draw while dragging */ + WM_MANIPULATOR_DRAW_VALUE = (1 << 2), /* draw an indicator for the current value while dragging */ + WM_MANIPULATOR_HIDDEN = (1 << 3), +} eWM_ManipulatorFlag; + +/** + * #wmManipulatorGroupType.flag + * Flags that influence the behavior of all manipulators in the group. + */ +typedef enum eWM_ManipulatorGroupTypeFlag { + /* Mark manipulator-group as being 3D */ + WM_MANIPULATORGROUPTYPE_3D = (1 << 0), + /* Scale manipulators as 3D object that respects zoom (otherwise zoom independent draw size). + * note: currently only for 3D views, 2D support needs adding. */ + WM_MANIPULATORGROUPTYPE_SCALE = (1 << 1), + /* Manipulators can be depth culled with scene objects (covered by other geometry - TODO) */ + WM_MANIPULATORGROUPTYPE_DEPTH_3D = (1 << 2), + /* Manipulators can be selected */ + WM_MANIPULATORGROUPTYPE_SELECT = (1 << 3), + /* The manipulator group is to be kept (not removed on loading a new file for eg). */ + WM_MANIPULATORGROUPTYPE_PERSISTENT = (1 << 4), + /* Show all other manipulators when interacting. */ + WM_MANIPULATORGROUPTYPE_DRAW_MODAL_ALL = (1 << 5), +} eWM_ManipulatorGroupTypeFlag; + +/** + * #wmManipulatorMapType.type_update_flag + * Manipulator-map type update flag + */ +typedef enum eWM_ManipulatorMapTypeUpdateFlag { + /* A new type has been added, needs to be initialized for all views. */ + WM_MANIPULATORMAPTYPE_UPDATE_INIT = (1 << 0), + WM_MANIPULATORMAPTYPE_UPDATE_REMOVE = (1 << 1), + + /* Needed because keymap may be registered before and after window initialization. + * So we need to keep track of keymap initialization separately. */ + WM_MANIPULATORMAPTYPE_KEYMAP_INIT = (1 << 2), +} eWM_ManipulatorMapTypeUpdateFlag; + /* -------------------------------------------------------------------- */ /* wmManipulator */ +/** + * \brief Manipulator tweak flag. + * Bitflag passed to manipulator while tweaking. + * + * \note Manipulators are responsible for handling this #wmManipulator.modal callback!. + */ +typedef enum { + /* Drag with extra precision (Shift). */ + WM_MANIPULATOR_TWEAK_PRECISE = (1 << 0), + /* Drag with snap enabled (Ctrl). */ + WM_MANIPULATOR_TWEAK_SNAP = (1 << 1), +} eWM_ManipulatorTweak; + +#include "wm_manipulator_fn.h" + /* manipulators are set per region by registering them on manipulator-maps */ struct wmManipulator { struct wmManipulator *next, *prev; - char name[64 + 4]; /* MAX_NAME + 4 for unique '.001', '.002', etc suffix */ - /* While we don't have a real type, use this to put type-like vars. */ const struct wmManipulatorType *type; @@ -73,8 +144,10 @@ struct wmManipulator { /* rna pointer to access properties */ struct PointerRNA *ptr; - int flag; /* flags that influence the behavior or how the manipulators are drawn */ - short state; /* state flags (active, highlighted, selected) */ + /* flags that influence the behavior or how the manipulators are drawn */ + eWM_ManipulatorFlag flag; + /* state flags (active, highlighted, selected) */ + eWM_ManipulatorState state; /* Optional ID for highlighting different parts of this manipulator. */ int highlight_part; @@ -87,6 +160,10 @@ struct wmManipulator { * besides this it's up to the manipulators internal code how the * rotation components are used for drawing and interaction. */ + + /* The space this manipulator is being modified in. */ + float matrix_space[4][4]; + /* Transformation of this manipulator. */ float matrix_basis[4][4]; /* custom offset from origin */ float matrix_offset[4][4]; @@ -133,7 +210,6 @@ typedef struct wmManipulatorProperty { wmManipulatorPropertyFnSet value_set_fn; wmManipulatorPropertyFnRangeGet range_get_fn; wmManipulatorPropertyFnFree free_fn; - const struct bContext *context; void *user_data; } custom_func; } wmManipulatorProperty; @@ -152,7 +228,6 @@ typedef struct wmManipulatorPropertyType { } wmManipulatorPropertyType; - /** * Simple utility wrapper for storing a single manipulator as wmManipulatorGroup.customdata (which gets freed). */ @@ -165,36 +240,6 @@ struct wmManipulatorMapType_Params { short regionid; }; - -/* wmManipulator.flag - * Flags for individual manipulators. */ -enum { - WM_MANIPULATOR_DRAW_HOVER = (1 << 0), /* draw *only* while hovering */ - WM_MANIPULATOR_DRAW_ACTIVE = (1 << 1), /* draw while dragging */ - WM_MANIPULATOR_DRAW_VALUE = (1 << 2), /* draw an indicator for the current value while dragging */ - WM_MANIPULATOR_HIDDEN = (1 << 3), -}; - -/* wmManipulator.state */ -enum { - WM_MANIPULATOR_STATE_HIGHLIGHT = (1 << 0), /* while hovered */ - WM_MANIPULATOR_STATE_ACTIVE = (1 << 1), /* while dragging */ - WM_MANIPULATOR_STATE_SELECT = (1 << 2), -}; - -/** - * \brief Manipulator tweak flag. - * Bitflag passed to manipulator while tweaking. - * - * \note Manipulators are responsible for handling this #wmManipulator.modal callback!. - */ -enum { - /* Drag with extra precision (Shift). */ - WM_MANIPULATOR_TWEAK_PRECISE = (1 << 0), - /* Drag with snap enabled (Ctrl). */ - WM_MANIPULATOR_TWEAK_SNAP = (1 << 1), -}; - typedef struct wmManipulatorType { const char *idname; /* MAX_NAME */ @@ -238,7 +283,7 @@ typedef struct wmManipulatorType { wmManipulatorFnCursorGet cursor_get; /* called when manipulator selection state changes */ - wmManipulatorFnSelect select; + wmManipulatorFnSelectRefresh select_refresh; /* RNA for properties */ struct StructRNA *srna; @@ -293,10 +338,10 @@ typedef struct wmManipulatorGroupType { /* RNA integration */ ExtensionRNA ext; - int flag; + eWM_ManipulatorGroupTypeFlag flag; - /* eManipulatorMapTypeUpdateFlags (so we know which group type to update) */ - uchar type_update_flag; + /* So we know which group type to update. */ + eWM_ManipulatorMapTypeUpdateFlag type_update_flag; /* same as manipulator-maps, so registering/unregistering goes to the correct region */ struct wmManipulatorMapType_Params mmap_params; @@ -316,52 +361,21 @@ typedef struct wmManipulatorGroup { void *customdata; void (*customdata_free)(void *); /* for freeing customdata from above */ - int flag; /* private */ - int pad; + int init_flag; /* private (C source only) */ } wmManipulatorGroup; -/** - * Manipulator-map type update flag: `wmManipulatorMapType.type_update_flag` - */ -enum eManipulatorMapTypeUpdateFlags { - /* A new type has been added, needs to be initialized for all views. */ - WM_MANIPULATORMAPTYPE_UPDATE_INIT = (1 << 0), - WM_MANIPULATORMAPTYPE_UPDATE_REMOVE = (1 << 1), -}; - -/** - * wmManipulatorGroupType.flag - * Flags that influence the behavior of all manipulators in the group. - */ -enum { - /* Mark manipulator-group as being 3D */ - WM_MANIPULATORGROUPTYPE_3D = (1 << 0), - /* Scale manipulators as 3D object that respects zoom (otherwise zoom independent draw size). - * note: currently only for 3D views, 2D support needs adding. */ - WM_MANIPULATORGROUPTYPE_SCALE = (1 << 1), - /* Manipulators can be depth culled with scene objects (covered by other geometry - TODO) */ - WM_MANIPULATORGROUPTYPE_DEPTH_3D = (1 << 2), - /* Manipulators can be selected */ - WM_MANIPULATORGROUPTYPE_SELECT = (1 << 3), - /* The manipulator group is to be kept (not removed on loading a new file for eg). */ - WM_MANIPULATORGROUPTYPE_PERSISTENT = (1 << 4), -}; - - /* -------------------------------------------------------------------- */ /* wmManipulatorMap */ /** * Pass a value of this enum to #WM_manipulatormap_draw to tell it what to draw. */ -enum { - /* Draw 2D manipulator-groups (ManipulatorGroupType.is_3d == false) */ +typedef enum eWM_ManipulatorMapDrawStep { + /** Draw 2D manipulator-groups (#WM_MANIPULATORGROUPTYPE_3D not set). */ WM_MANIPULATORMAP_DRAWSTEP_2D = 0, - /* Draw 3D manipulator-groups (ManipulatorGroupType.is_3d == true) */ + /** Draw 3D manipulator-groups (#WM_MANIPULATORGROUPTYPE_3D set). */ WM_MANIPULATORMAP_DRAWSTEP_3D, - /* Draw only depth culled manipulators (WM_MANIPULATOR_SCENE_DEPTH flag). - * Note that these are expected to be 3D manipulators too. */ - WM_MANIPULATORMAP_DRAWSTEP_IN_SCENE, -}; +} eWM_ManipulatorMapDrawStep; +#define WM_MANIPULATORMAP_DRAWSTEP_MAX 2 #endif /* __WM_MANIPULATOR_TYPES_H__ */ diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c index d8d530a4db9..3f10864995f 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c @@ -65,7 +65,7 @@ #include "wm_manipulator_intern.h" static void wm_manipulator_register( - wmManipulatorGroup *mgroup, wmManipulator *mpr, const char *name); + wmManipulatorGroup *mgroup, wmManipulator *mpr); /** * \note Follow #wm_operator_create convention. @@ -94,6 +94,7 @@ static wmManipulator *wm_manipulator_create( WM_manipulator_properties_sanitize(mpr->ptr, 0); + unit_m4(mpr->matrix_space); unit_m4(mpr->matrix_basis); unit_m4(mpr->matrix_offset); @@ -102,11 +103,11 @@ static wmManipulator *wm_manipulator_create( wmManipulator *WM_manipulator_new_ptr( const wmManipulatorType *wt, wmManipulatorGroup *mgroup, - const char *name, PointerRNA *properties) + PointerRNA *properties) { wmManipulator *mpr = wm_manipulator_create(wt, properties); - wm_manipulator_register(mgroup, mpr, name); + wm_manipulator_register(mgroup, mpr); if (mpr->type->setup != NULL) { mpr->type->setup(mpr); @@ -122,33 +123,10 @@ wmManipulator *WM_manipulator_new_ptr( */ wmManipulator *WM_manipulator_new( const char *idname, wmManipulatorGroup *mgroup, - const char *name, PointerRNA *properties) + PointerRNA *properties) { const wmManipulatorType *wt = WM_manipulatortype_find(idname, false); - return WM_manipulator_new_ptr(wt, mgroup, name, properties); -} - -/** - * Assign an idname that is unique in \a mgroup to \a manipulator. - * - * \param rawname: Name used as basis to define final unique idname. - */ -static void manipulator_unique_idname_set(wmManipulatorGroup *mgroup, wmManipulator *mpr, const char *rawname) -{ - BLI_snprintf(mpr->name, sizeof(mpr->name), "%s_%s", mgroup->type->idname, rawname); - - /* ensure name is unique, append '.001', '.002', etc if not */ - BLI_uniquename(&mgroup->manipulators, mpr, "Manipulator", '.', - offsetof(wmManipulator, name), sizeof(mpr->name)); -} - -void WM_manipulator_name_set(wmManipulatorGroup *mgroup, wmManipulator *mpr, const char *name) -{ - BLI_strncpy(mpr->name, name, sizeof(mpr->name)); - - /* ensure name is unique, append '.001', '.002', etc if not */ - BLI_uniquename(&mgroup->manipulators, mpr, "Manipulator", '.', - offsetof(wmManipulator, name), sizeof(mpr->name)); + return WM_manipulator_new_ptr(wt, mgroup, properties); } /** @@ -173,18 +151,18 @@ static void manipulator_init(wmManipulator *mpr) * * \note Not to be confused with type registration from RNA. */ -static void wm_manipulator_register(wmManipulatorGroup *mgroup, wmManipulator *mpr, const char *name) +static void wm_manipulator_register(wmManipulatorGroup *mgroup, wmManipulator *mpr) { manipulator_init(mpr); - manipulator_unique_idname_set(mgroup, mpr, name); wm_manipulatorgroup_manipulator_register(mgroup, mpr); } /** - * Free \a manipulator and unlink from \a manipulatorlist. - * \a manipulatorlist is allowed to be NULL. + * \warning this doesn't check #wmManipulatorMap (highlight, selection etc). + * Typical use is when freeing the windowing data, + * where caller can manage clearing selection, highlight... etc. */ -void WM_manipulator_free(ListBase *manipulatorlist, wmManipulatorMap *mmap, wmManipulator *mpr, bContext *C) +void WM_manipulator_free(wmManipulator *mpr) { #ifdef WITH_PYTHON if (mpr->py_instance) { @@ -194,16 +172,6 @@ void WM_manipulator_free(ListBase *manipulatorlist, wmManipulatorMap *mmap, wmMa } #endif - if (mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT) { - wm_manipulatormap_highlight_set(mmap, C, NULL, 0); - } - if (mpr->state & WM_MANIPULATOR_STATE_ACTIVE) { - wm_manipulatormap_active_set(mmap, C, NULL, NULL); - } - if (mpr->state & WM_MANIPULATOR_STATE_SELECT) { - wm_manipulator_deselect(mmap, mpr); - } - if (mpr->op_data.ptr.data) { WM_operator_properties_free(&mpr->op_data.ptr); } @@ -223,14 +191,34 @@ void WM_manipulator_free(ListBase *manipulatorlist, wmManipulatorMap *mmap, wmMa } } + MEM_freeN(mpr); +} + +/** + * Free \a manipulator and unlink from \a manipulatorlist. + * \a manipulatorlist is allowed to be NULL. + */ +void WM_manipulator_unlink(ListBase *manipulatorlist, wmManipulatorMap *mmap, wmManipulator *mpr, bContext *C) +{ + if (mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT) { + wm_manipulatormap_highlight_set(mmap, C, NULL, 0); + } + if (mpr->state & WM_MANIPULATOR_STATE_MODAL) { + wm_manipulatormap_modal_set(mmap, C, NULL, NULL); + } + /* Unlink instead of setting so we don't run callbacks. */ + if (mpr->state & WM_MANIPULATOR_STATE_SELECT) { + WM_manipulator_select_unlink(mmap, mpr); + } + if (manipulatorlist) { BLI_remlink(manipulatorlist, mpr); } BLI_assert(mmap->mmap_context.highlight != mpr); - BLI_assert(mmap->mmap_context.active != mpr); + BLI_assert(mmap->mmap_context.modal != mpr); - MEM_freeN(mpr); + WM_manipulator_free(mpr); } /* -------------------------------------------------------------------- */ @@ -386,73 +374,67 @@ void WM_manipulator_set_fn_custom_modal(struct wmManipulator *mpr, wmManipulator /* -------------------------------------------------------------------- */ /** - * Remove \a manipulator from selection. + * Add/Remove \a manipulator to selection. * Reallocates memory for selected manipulators so better not call for selecting multiple ones. * * \return if the selection has changed. */ -bool wm_manipulator_deselect(wmManipulatorMap *mmap, wmManipulator *mpr) +bool wm_manipulator_select_set_ex( + wmManipulatorMap *mmap, wmManipulator *mpr, bool select, + bool use_array, bool use_callback) { - if (!mmap->mmap_context.selected) - return false; - - wmManipulator ***sel = &mmap->mmap_context.selected; - int *selected_len = &mmap->mmap_context.selected_len; bool changed = false; - /* caller should check! */ - BLI_assert(mpr->state & WM_MANIPULATOR_STATE_SELECT); - - /* remove manipulator from selected_manipulators array */ - for (int i = 0; i < (*selected_len); i++) { - if ((*sel)[i] == mpr) { - for (int j = i; j < ((*selected_len) - 1); j++) { - (*sel)[j] = (*sel)[j + 1]; + if (select) { + if ((mpr->state & WM_MANIPULATOR_STATE_SELECT) == 0) { + if (use_array) { + wm_manipulatormap_select_array_push_back(mmap, mpr); } + mpr->state |= WM_MANIPULATOR_STATE_SELECT; changed = true; - break; } } - - /* update array data */ - if ((*selected_len) <= 1) { - wm_manipulatormap_selected_clear(mmap); - } else { - *sel = MEM_reallocN(*sel, sizeof(**sel) * (*selected_len)); - (*selected_len)--; + if (mpr->state & WM_MANIPULATOR_STATE_SELECT) { + if (use_array) { + wm_manipulatormap_select_array_remove(mmap, mpr); + } + mpr->state &= ~WM_MANIPULATOR_STATE_SELECT; + changed = true; + } + } + + /* In the case of unlinking we only want to remove from the array + * and not write to the external state */ + if (use_callback && changed) { + if (mpr->type->select_refresh) { + mpr->type->select_refresh(mpr); + } } - mpr->state &= ~WM_MANIPULATOR_STATE_SELECT; return changed; } -/** - * Add \a manipulator to selection. - * Reallocates memory for selected manipulators so better not call for selecting multiple ones. - * - * \return if the selection has changed. - */ -bool wm_manipulator_select(bContext *C, wmManipulatorMap *mmap, wmManipulator *mpr) +/* Remove from selection array without running callbacks. */ +bool WM_manipulator_select_unlink(wmManipulatorMap *mmap, wmManipulator *mpr) { - wmManipulator ***sel = &mmap->mmap_context.selected; - int *selected_len = &mmap->mmap_context.selected_len; - - if (!mpr || (mpr->state & WM_MANIPULATOR_STATE_SELECT)) - return false; - - (*selected_len)++; + return wm_manipulator_select_set_ex(mmap, mpr, false, true, false); +} - *sel = MEM_reallocN(*sel, sizeof(wmManipulator *) * (*selected_len)); - (*sel)[(*selected_len) - 1] = mpr; +bool WM_manipulator_select_set(wmManipulatorMap *mmap, wmManipulator *mpr, bool select) +{ + return wm_manipulator_select_set_ex(mmap, mpr, select, true, true); +} - mpr->state |= WM_MANIPULATOR_STATE_SELECT; - if (mpr->type->select) { - mpr->type->select(C, mpr, SEL_SELECT); +bool wm_manipulator_select_and_highlight(bContext *C, wmManipulatorMap *mmap, wmManipulator *mpr) +{ + if (WM_manipulator_select_set(mmap, mpr, true)) { + wm_manipulatormap_highlight_set(mmap, C, mpr, mpr->highlight_part); + return true; + } + else { + return false; } - wm_manipulatormap_highlight_set(mmap, C, mpr, mpr->highlight_part); - - return true; } void wm_manipulator_calculate_scale(wmManipulator *mpr, const bContext *C) @@ -509,10 +491,10 @@ int wm_manipulator_is_visible(wmManipulator *mpr) if (mpr->flag & WM_MANIPULATOR_HIDDEN) { return 0; } - if ((mpr->state & WM_MANIPULATOR_STATE_ACTIVE) && - !(mpr->flag & (WM_MANIPULATOR_DRAW_ACTIVE | WM_MANIPULATOR_DRAW_VALUE))) + if ((mpr->state & WM_MANIPULATOR_STATE_MODAL) && + !(mpr->flag & (WM_MANIPULATOR_DRAW_MODAL | WM_MANIPULATOR_DRAW_VALUE))) { - /* don't draw while active (while dragging) */ + /* don't draw while modal (dragging) */ return 0; } if ((mpr->flag & WM_MANIPULATOR_DRAW_HOVER) && diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c index 126c866d600..7dd696caf39 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c @@ -91,11 +91,24 @@ wmManipulatorGroup *wm_manipulatorgroup_new_from_type( void wm_manipulatorgroup_free(bContext *C, wmManipulatorGroup *mgroup) { wmManipulatorMap *mmap = mgroup->parent_mmap; + + /* Similar to WM_manipulator_unlink, but only to keep mmap state correct, + * we don't want to run callbacks. */ + if (mmap->mmap_context.highlight && mmap->mmap_context.highlight->parent_mgroup == mgroup) { + wm_manipulatormap_highlight_set(mmap, C, NULL, 0); + } + if (mmap->mmap_context.modal && mmap->mmap_context.modal->parent_mgroup == mgroup) { + wm_manipulatormap_modal_set(mmap, C, NULL, NULL); + } + for (wmManipulator *mpr = mgroup->manipulators.first, *mpr_next; mpr; mpr = mpr_next) { mpr_next = mpr->next; - WM_manipulator_free(&mgroup->manipulators, mmap, mpr, C); + if (mmap->mmap_context.select.len) { + WM_manipulator_select_unlink(mmap, mpr); + } + WM_manipulator_free(mpr); } - BLI_assert(BLI_listbase_is_empty(&mgroup->manipulators)); + BLI_listbase_clear(&mgroup->manipulators); #ifdef WITH_PYTHON if (mgroup->py_instance) { @@ -127,7 +140,7 @@ void wm_manipulatorgroup_free(bContext *C, wmManipulatorGroup *mgroup) */ void wm_manipulatorgroup_manipulator_register(wmManipulatorGroup *mgroup, wmManipulator *mpr) { - BLI_assert(!BLI_findstring(&mgroup->manipulators, mpr->name, offsetof(wmManipulator, name))); + BLI_assert(BLI_findindex(&mgroup->manipulators, mpr) == -1); BLI_addtail(&mgroup->manipulators, mpr); mpr->parent_mgroup = mgroup; } @@ -166,7 +179,7 @@ void wm_manipulatorgroup_intersectable_manipulators_to_list(const wmManipulatorG void wm_manipulatorgroup_ensure_initialized(wmManipulatorGroup *mgroup, const bContext *C) { /* prepare for first draw */ - if (UNLIKELY((mgroup->flag & WM_MANIPULATORGROUP_INITIALIZED) == 0)) { + if (UNLIKELY((mgroup->init_flag & WM_MANIPULATORGROUP_INITIALIZED) == 0)) { mgroup->type->setup(C, mgroup); /* Not ideal, initialize keymap here, needed for RNA runtime generated manipulators. */ @@ -177,7 +190,7 @@ void wm_manipulatorgroup_ensure_initialized(wmManipulatorGroup *mgroup, const bC BLI_assert(wgt->keymap != NULL); } - mgroup->flag |= WM_MANIPULATORGROUP_INITIALIZED; + mgroup->init_flag |= WM_MANIPULATORGROUP_INITIALIZED; } } @@ -187,21 +200,34 @@ bool wm_manipulatorgroup_is_visible(const wmManipulatorGroup *mgroup, const bCon return (!mgroup->type->poll || mgroup->type->poll(C, mgroup->type)); } -bool wm_manipulatorgroup_is_visible_in_drawstep(const wmManipulatorGroup *mgroup, const int drawstep) +bool wm_manipulatorgroup_is_visible_in_drawstep( + const wmManipulatorGroup *mgroup, const eWM_ManipulatorMapDrawStep drawstep) { switch (drawstep) { case WM_MANIPULATORMAP_DRAWSTEP_2D: return (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) == 0; case WM_MANIPULATORMAP_DRAWSTEP_3D: return (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D); - case WM_MANIPULATORMAP_DRAWSTEP_IN_SCENE: - return (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_DEPTH_3D); default: BLI_assert(0); return false; } } +bool wm_manipulatorgroup_is_any_selected(const wmManipulatorGroup *mgroup) +{ + if (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_SELECT) { + for (const wmManipulator *mpr = mgroup->manipulators.first; mpr; mpr = mpr->next) { + if (mpr->state & WM_MANIPULATOR_STATE_SELECT) { + return true; + } + } + } + return false; +} + +/** \} */ + /** \name Manipulator operators * * Basic operators for manipulator interaction with user configurable keymaps. @@ -212,7 +238,7 @@ static int manipulator_select_invoke(bContext *C, wmOperator *op, const wmEvent { ARegion *ar = CTX_wm_region(C); wmManipulatorMap *mmap = ar->manipulator_map; - wmManipulator ***sel = &mmap->mmap_context.selected; + wmManipulatorMapSelectState *msel = &mmap->mmap_context.select; wmManipulator *highlight = mmap->mmap_context.highlight; bool extend = RNA_boolean_get(op->ptr, "extend"); @@ -221,8 +247,9 @@ static int manipulator_select_invoke(bContext *C, wmOperator *op, const wmEvent /* deselect all first */ if (extend == false && deselect == false && toggle == false) { - wm_manipulatormap_deselect_all(mmap, sel); - BLI_assert(*sel == NULL && mmap->mmap_context.selected_len == 0); + wm_manipulatormap_deselect_all(mmap); + BLI_assert(msel->items == NULL && msel->len == 0); + UNUSED_VARS_NDEBUG(msel); } if (highlight) { @@ -235,11 +262,11 @@ static int manipulator_select_invoke(bContext *C, wmOperator *op, const wmEvent } if (deselect) { - if (is_selected && wm_manipulator_deselect(mmap, highlight)) { + if (is_selected && WM_manipulator_select_set(mmap, highlight, false)) { redraw = true; } } - else if (wm_manipulator_select(C, mmap, highlight)) { + else if (wm_manipulator_select_and_highlight(C, mmap, highlight)) { redraw = true; } @@ -274,7 +301,7 @@ void MANIPULATORGROUP_OT_manipulator_select(wmOperatorType *ot) typedef struct ManipulatorTweakData { wmManipulatorMap *mmap; - wmManipulator *active; + wmManipulator *mpr_modal; int init_event; /* initial event type */ int flag; /* tweak flags */ @@ -283,17 +310,17 @@ typedef struct ManipulatorTweakData { static void manipulator_tweak_finish(bContext *C, wmOperator *op, const bool cancel) { ManipulatorTweakData *mtweak = op->customdata; - if (mtweak->active->type->exit) { - mtweak->active->type->exit(C, mtweak->active, cancel); + if (mtweak->mpr_modal->type->exit) { + mtweak->mpr_modal->type->exit(C, mtweak->mpr_modal, cancel); } - wm_manipulatormap_active_set(mtweak->mmap, C, NULL, NULL); + wm_manipulatormap_modal_set(mtweak->mmap, C, NULL, NULL); MEM_freeN(mtweak); } static int manipulator_tweak_modal(bContext *C, wmOperator *op, const wmEvent *event) { ManipulatorTweakData *mtweak = op->customdata; - wmManipulator *mpr = mtweak->active; + wmManipulator *mpr = mtweak->mpr_modal; if (mpr == NULL) { BLI_assert(0); @@ -361,7 +388,7 @@ static int manipulator_tweak_invoke(bContext *C, wmOperator *op, const wmEvent * /* activate highlighted manipulator */ - wm_manipulatormap_active_set(mmap, C, event, mpr); + wm_manipulatormap_modal_set(mmap, C, event, mpr); /* XXX temporary workaround for modal manipulator operator * conflicting with modal operator attached to manipulator */ @@ -374,8 +401,8 @@ static int manipulator_tweak_invoke(bContext *C, wmOperator *op, const wmEvent * ManipulatorTweakData *mtweak = MEM_mallocN(sizeof(ManipulatorTweakData), __func__); - mtweak->init_event = event->type; - mtweak->active = mmap->mmap_context.highlight; + mtweak->init_event = WM_userdef_event_type_from_keymap_type(event->type); + mtweak->mpr_modal = mmap->mmap_context.highlight; mtweak->mmap = mmap; mtweak->flag = 0; @@ -480,6 +507,7 @@ wmKeyMap *WM_manipulatorgroup_keymap_common_select( wmKeyMap *km = WM_keymap_find(config, wgt->name, wgt->mmap_params.spaceid, wgt->mmap_params.regionid); WM_keymap_add_item(km, "MANIPULATORGROUP_OT_manipulator_tweak", ACTIONMOUSE, KM_PRESS, KM_ANY, 0); + WM_keymap_add_item(km, "MANIPULATORGROUP_OT_manipulator_tweak", EVT_TWEAK_S, KM_ANY, 0, 0); manipulatorgroup_tweak_modal_keymap(config, wgt->name); wmKeyMapItem *kmi = WM_keymap_add_item(km, "MANIPULATORGROUP_OT_manipulator_select", SELECTMOUSE, KM_PRESS, 0, 0); @@ -553,13 +581,18 @@ wmManipulatorGroupTypeRef *WM_manipulatormaptype_group_link_ptr( return wgt_ref; } -void WM_manipulatormaptype_group_init_runtime( - const Main *bmain, wmManipulatorMapType *mmap_type, +void WM_manipulatormaptype_group_init_runtime_keymap( + const Main *bmain, wmManipulatorGroupType *wgt) { /* init keymap - on startup there's an extra call to init keymaps for 'permanent' manipulator-groups */ wm_manipulatorgrouptype_setup_keymap(wgt, ((wmWindowManager *)bmain->wm.first)->defaultconf); +} +void WM_manipulatormaptype_group_init_runtime( + const Main *bmain, wmManipulatorMapType *mmap_type, + wmManipulatorGroupType *wgt) +{ /* now create a manipulator for all existing areas */ for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) { for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { @@ -632,8 +665,13 @@ void WM_manipulatormaptype_group_unlink( void wm_manipulatorgrouptype_setup_keymap( wmManipulatorGroupType *wgt, wmKeyConfig *keyconf) { - wgt->keymap = wgt->setup_keymap(wgt, keyconf); - wgt->keyconf = keyconf; + /* Use flag since setup_keymap may return NULL, + * in that case we better not keep calling it. */ + if (wgt->type_update_flag & WM_MANIPULATORMAPTYPE_KEYMAP_INIT) { + wgt->keymap = wgt->setup_keymap(wgt, keyconf); + wgt->keyconf = keyconf; + wgt->type_update_flag &= ~WM_MANIPULATORMAPTYPE_KEYMAP_INIT; + } } /** \} */ /* wmManipulatorGroupType */ diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_group_type.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_group_type.c index 0f21a7448b5..d474788caff 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_group_type.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_group_type.c @@ -90,9 +90,16 @@ static void wm_manipulatorgrouptype_append__end(wmManipulatorGroupType *wgt) BLI_assert(wgt->name != NULL); BLI_assert(wgt->idname != NULL); + wgt->type_update_flag |= WM_MANIPULATORMAPTYPE_KEYMAP_INIT; + /* if not set, use default */ if (wgt->setup_keymap == NULL) { - wgt->setup_keymap = WM_manipulatorgroup_keymap_common; + if (wgt->flag & WM_MANIPULATORGROUPTYPE_SELECT) { + wgt->setup_keymap = WM_manipulatorgroup_keymap_common_select; + } + else { + wgt->setup_keymap = WM_manipulatorgroup_keymap_common; + } } BLI_ghash_insert(global_manipulatorgrouptype_hash, (void *)wgt->idname, wgt); diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h index 6ddde1df9de..06578fee555 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h @@ -38,8 +38,11 @@ struct GHashIterator; /* -------------------------------------------------------------------- */ /* wmManipulator */ -bool wm_manipulator_deselect(struct wmManipulatorMap *mmap, struct wmManipulator *mpr); -bool wm_manipulator_select(bContext *C, struct wmManipulatorMap *mmap, struct wmManipulator *mpr); + +bool wm_manipulator_select_set_ex( + struct wmManipulatorMap *mmap, struct wmManipulator *mpr, bool select, + bool use_array, bool use_callback); +bool wm_manipulator_select_and_highlight(bContext *C, struct wmManipulatorMap *mmap, struct wmManipulator *mpr); void wm_manipulator_calculate_scale(struct wmManipulator *mpr, const bContext *C); void wm_manipulator_update(struct wmManipulator *mpr, const bContext *C, const bool refresh_map); @@ -73,7 +76,8 @@ void wm_manipulatorgroup_intersectable_manipulators_to_list( const struct wmManipulatorGroup *mgroup, struct ListBase *listbase); void wm_manipulatorgroup_ensure_initialized(struct wmManipulatorGroup *mgroup, const struct bContext *C); bool wm_manipulatorgroup_is_visible(const struct wmManipulatorGroup *mgroup, const struct bContext *C); -bool wm_manipulatorgroup_is_visible_in_drawstep(const struct wmManipulatorGroup *mgroup, const int drawstep); +bool wm_manipulatorgroup_is_visible_in_drawstep( + const struct wmManipulatorGroup *mgroup, const eWM_ManipulatorMapDrawStep drawstep); void wm_manipulatorgrouptype_setup_keymap( struct wmManipulatorGroupType *wgt, struct wmKeyConfig *keyconf); @@ -82,13 +86,18 @@ void wm_manipulatorgrouptype_setup_keymap( /* -------------------------------------------------------------------- */ /* wmManipulatorMap */ +typedef struct wmManipulatorMapSelectState { + struct wmManipulator **items; + int len, len_alloc; +} wmManipulatorMapSelectState; + struct wmManipulatorMap { - struct wmManipulatorMap *next, *prev; struct wmManipulatorMapType *type; ListBase groups; /* wmManipulatorGroup */ - char update_flag; /* private, update tagging */ + /* private, update tagging (enum defined in C source). */ + char update_flag[WM_MANIPULATORMAP_DRAWSTEP_MAX]; /** * \brief Manipulator map runtime context @@ -99,12 +108,10 @@ struct wmManipulatorMap { struct { /* we redraw the manipulator-map when this changes */ struct wmManipulator *highlight; - /* user has clicked this manipulator and it gets all input */ - struct wmManipulator *active; - /* array for all selected manipulators - * TODO check on using BLI_array */ - struct wmManipulator **selected; - int selected_len; + /* User has clicked this manipulator and it gets all input. */ + struct wmManipulator *modal; + /* array for all selected manipulators */ + struct wmManipulatorMapSelectState select; } mmap_context; }; @@ -121,10 +128,13 @@ struct wmManipulatorMapType { ListBase grouptype_refs; /* eManipulatorMapTypeUpdateFlags */ - uchar type_update_flag; + eWM_ManipulatorMapTypeUpdateFlag type_update_flag; }; -void wm_manipulatormap_selected_clear(struct wmManipulatorMap *mmap); -bool wm_manipulatormap_deselect_all(struct wmManipulatorMap *mmap, struct wmManipulator ***sel); +void wm_manipulatormap_select_array_clear(struct wmManipulatorMap *mmap); +bool wm_manipulatormap_deselect_all(struct wmManipulatorMap *mmap); +void wm_manipulatormap_select_array_shrink(struct wmManipulatorMap *mmap, int len_subtract); +void wm_manipulatormap_select_array_push_back(struct wmManipulatorMap *mmap, wmManipulator *mpr); +void wm_manipulatormap_select_array_remove(struct wmManipulatorMap *mmap, wmManipulator *mpr); #endif
\ No newline at end of file diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c index f5ef5572fd4..085b7b1c787 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c @@ -64,23 +64,94 @@ static ListBase manipulatormaptypes = {NULL, NULL}; * Update when manipulator-map types change. */ /* so operator removal can trigger update */ -enum { +typedef enum eWM_ManipulatorGroupTypeGlobalFlag { WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_INIT = (1 << 0), WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_REMOVE = (1 << 1), -}; +} eWM_ManipulatorGroupTypeGlobalFlag; -static char wm_mmap_type_update_flag = 0; +static eWM_ManipulatorGroupTypeGlobalFlag wm_mmap_type_update_flag = 0; /** * Manipulator-map update tagging. */ -enum eManipulatorMapUpdateFlags { - /* Tag manipulator-map for refresh. */ - MANIPULATORMAP_REFRESH = (1 << 0), +enum { + /** #manipulatormap_prepare_drawing has run */ + MANIPULATORMAP_IS_PREPARE_DRAW = (1 << 0), + MANIPULATORMAP_IS_REFRESH_CALLBACK = (1 << 1), }; /* -------------------------------------------------------------------- */ +/** \name wmManipulatorMap Selection Array API + * + * Just handle ``wm_manipulatormap_select_array_*``, not flags or callbacks. + * + * \{ */ + +static void wm_manipulatormap_select_array_ensure_len_alloc(wmManipulatorMap *mmap, int len) +{ + wmManipulatorMapSelectState *msel = &mmap->mmap_context.select; + if (len <= msel->len_alloc) { + return; + } + msel->items = MEM_reallocN(msel->items, sizeof(*msel->items) * len); + msel->len_alloc = len; +} + +void wm_manipulatormap_select_array_clear(wmManipulatorMap *mmap) +{ + wmManipulatorMapSelectState *msel = &mmap->mmap_context.select; + MEM_SAFE_FREE(msel->items); + msel->len = 0; + msel->len_alloc = 0; +} + +void wm_manipulatormap_select_array_shrink(wmManipulatorMap *mmap, int len_subtract) +{ + wmManipulatorMapSelectState *msel = &mmap->mmap_context.select; + msel->len -= len_subtract; + if (msel->len <= 0) { + wm_manipulatormap_select_array_clear(mmap); + } + else { + if (msel->len < msel->len_alloc / 2) { + msel->items = MEM_reallocN(msel->items, sizeof(*msel->items) * msel->len); + msel->len_alloc = msel->len; + } + } +} + +void wm_manipulatormap_select_array_push_back(wmManipulatorMap *mmap, wmManipulator *mpr) +{ + wmManipulatorMapSelectState *msel = &mmap->mmap_context.select; + BLI_assert(msel->len <= msel->len_alloc); + if (msel->len == msel->len_alloc) { + msel->len_alloc = (msel->len + 1) * 2; + msel->items = MEM_reallocN(msel->items, sizeof(*msel->items) * msel->len_alloc); + } + msel->items[msel->len++] = mpr; +} + +void wm_manipulatormap_select_array_remove(wmManipulatorMap *mmap, wmManipulator *mpr) +{ + wmManipulatorMapSelectState *msel = &mmap->mmap_context.select; + /* remove manipulator from selected_manipulators array */ + for (int i = 0; i < msel->len; i++) { + if (msel->items[i] == mpr) { + for (int j = i; j < (msel->len - 1); j++) { + msel->items[j] = msel->items[j + 1]; + } + wm_manipulatormap_select_array_shrink(mmap, 1); + break; + } + } + +} + +/** \} */ + + +/* -------------------------------------------------------------------- */ /** \name wmManipulatorMap * * \{ */ @@ -96,7 +167,7 @@ wmManipulatorMap *WM_manipulatormap_new_from_type( mmap = MEM_callocN(sizeof(wmManipulatorMap), "ManipulatorMap"); mmap->type = mmap_type; - mmap->update_flag = MANIPULATORMAP_REFRESH; + WM_manipulatormap_tag_refresh(mmap); /* create all manipulator-groups for this manipulator-map. We may create an empty one * too in anticipation of manipulators from operators etc */ @@ -107,16 +178,10 @@ wmManipulatorMap *WM_manipulatormap_new_from_type( return mmap; } -void wm_manipulatormap_selected_clear(wmManipulatorMap *mmap) -{ - MEM_SAFE_FREE(mmap->mmap_context.selected); - mmap->mmap_context.selected_len = 0; -} - void wm_manipulatormap_remove(wmManipulatorMap *mmap) { - if (!mmap) - return; + /* Clear first so further calls don't waste time trying to maintain correct array state. */ + wm_manipulatormap_select_array_clear(mmap); for (wmManipulatorGroup *mgroup = mmap->groups.first, *mgroup_next; mgroup; mgroup = mgroup_next) { mgroup_next = mgroup->next; @@ -125,8 +190,6 @@ void wm_manipulatormap_remove(wmManipulatorMap *mmap) } BLI_assert(BLI_listbase_is_empty(&mmap->groups)); - wm_manipulatormap_selected_clear(mmap); - MEM_freeN(mmap); } @@ -135,18 +198,47 @@ const ListBase *WM_manipulatormap_group_list(wmManipulatorMap *mmap) return &mmap->groups; } +bool WM_manipulatormap_is_any_selected(const wmManipulatorMap *mmap) +{ + return mmap->mmap_context.select.len != 0; +} + +/** + * \note We could use a callback to define bounds, for now just use matrix location. + */ +bool WM_manipulatormap_minmax( + const wmManipulatorMap *mmap, bool UNUSED(use_hidden), bool use_select, + float r_min[3], float r_max[3]) +{ + if (use_select) { + int i; + for (i = 0; i < mmap->mmap_context.select.len; i++) { + minmax_v3v3_v3(r_min, r_max, mmap->mmap_context.select.items[i]->matrix_basis[3]); + } + return i != 0; + } + else { + bool ok = false; + BLI_assert(!"TODO"); + return ok; + } +} + /** * Creates and returns idname hash table for (visible) manipulators in \a mmap * * \param poll Polling function for excluding manipulators. * \param data Custom data passed to \a poll + * + * TODO(campbell): this uses unreliable order, + * best we use an iterator function instead of a hash. */ static GHash *WM_manipulatormap_manipulator_hash_new( const bContext *C, wmManipulatorMap *mmap, bool (*poll)(const wmManipulator *, void *), void *data, const bool include_hidden) { - GHash *hash = BLI_ghash_str_new(__func__); + GHash *hash = BLI_ghash_ptr_new(__func__); /* collect manipulators */ for (wmManipulatorGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) { @@ -155,7 +247,7 @@ static GHash *WM_manipulatormap_manipulator_hash_new( if ((include_hidden || (mpr->flag & WM_MANIPULATOR_HIDDEN) == 0) && (!poll || poll(mpr, data))) { - BLI_ghash_insert(hash, mpr->name, mpr); + BLI_ghash_insert(hash, mpr, mpr); } } } @@ -167,18 +259,19 @@ static GHash *WM_manipulatormap_manipulator_hash_new( void WM_manipulatormap_tag_refresh(wmManipulatorMap *mmap) { if (mmap) { - mmap->update_flag |= MANIPULATORMAP_REFRESH; + /* We might want only to refresh some, for tag all steps. */ + for (int i = 0; i < WM_MANIPULATORMAP_DRAWSTEP_MAX; i++) { + mmap->update_flag[i] |= ( + MANIPULATORMAP_IS_PREPARE_DRAW | + MANIPULATORMAP_IS_REFRESH_CALLBACK); + } } } -static void manipulatormap_tag_updated(wmManipulatorMap *mmap) -{ - mmap->update_flag = 0; -} - static bool manipulator_prepare_drawing( wmManipulatorMap *mmap, wmManipulator *mpr, - const bContext *C, ListBase *draw_manipulators) + const bContext *C, ListBase *draw_manipulators, + const eWM_ManipulatorMapDrawStep drawstep) { int do_draw = wm_manipulator_is_visible(mpr); if (do_draw == 0) { @@ -187,7 +280,7 @@ static bool manipulator_prepare_drawing( else { if (do_draw & WM_MANIPULATOR_IS_VISIBLE_UPDATE) { /* hover manipulators need updating, even if we don't draw them */ - wm_manipulator_update(mpr, C, (mmap->update_flag & MANIPULATORMAP_REFRESH) != 0); + wm_manipulator_update(mpr, C, (mmap->update_flag[drawstep] & MANIPULATORMAP_IS_PREPARE_DRAW) != 0); } if (do_draw & WM_MANIPULATOR_IS_VISIBLE_DRAW) { BLI_addhead(draw_manipulators, BLI_genericNodeN(mpr)); @@ -203,19 +296,24 @@ static bool manipulator_prepare_drawing( * should be drawn to list \a draw_manipulators, note that added items need freeing. */ static void manipulatormap_prepare_drawing( - wmManipulatorMap *mmap, const bContext *C, ListBase *draw_manipulators, const int drawstep) + wmManipulatorMap *mmap, const bContext *C, ListBase *draw_manipulators, + const eWM_ManipulatorMapDrawStep drawstep) { if (!mmap || BLI_listbase_is_empty(&mmap->groups)) return; - wmManipulator *active_manipulator = mmap->mmap_context.active; + wmManipulator *mpr_modal = mmap->mmap_context.modal; /* only active manipulator needs updating */ - if (active_manipulator) { - if (manipulator_prepare_drawing(mmap, active_manipulator, C, draw_manipulators)) { - manipulatormap_tag_updated(mmap); + if (mpr_modal) { + if ((mpr_modal->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_DRAW_MODAL_ALL) == 0) { + if (wm_manipulatorgroup_is_visible_in_drawstep(mpr_modal->parent_mgroup, drawstep)) { + if (manipulator_prepare_drawing(mmap, mpr_modal, C, draw_manipulators, drawstep)) { + mmap->update_flag[drawstep] &= ~MANIPULATORMAP_IS_PREPARE_DRAW; + } + } + /* don't draw any other manipulators */ + return; } - /* don't draw any other manipulators */ - return; } for (wmManipulatorGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) { @@ -230,8 +328,9 @@ static void manipulatormap_prepare_drawing( wm_manipulatorgroup_ensure_initialized(mgroup, C); /* update data if needed */ /* XXX weak: Manipulator-group may skip refreshing if it's invisible (map gets untagged nevertheless) */ - if (mmap->update_flag & MANIPULATORMAP_REFRESH && mgroup->type->refresh) { + if ((mmap->update_flag[drawstep] & MANIPULATORMAP_IS_REFRESH_CALLBACK) && mgroup->type->refresh) { mgroup->type->refresh(C, mgroup); + /* cleared below */ } /* prepare drawing */ if (mgroup->type->draw_prepare) { @@ -239,11 +338,13 @@ static void manipulatormap_prepare_drawing( } for (wmManipulator *mpr = mgroup->manipulators.first; mpr; mpr = mpr->next) { - manipulator_prepare_drawing(mmap, mpr, C, draw_manipulators); + manipulator_prepare_drawing(mmap, mpr, C, draw_manipulators, drawstep); } } - manipulatormap_tag_updated(mmap); + mmap->update_flag[drawstep] &= + ~(MANIPULATORMAP_IS_REFRESH_CALLBACK | + MANIPULATORMAP_IS_PREPARE_DRAW); } /** @@ -308,7 +409,9 @@ static void manipulators_draw_list(const wmManipulatorMap *mmap, const bContext } } -void WM_manipulatormap_draw(wmManipulatorMap *mmap, const bContext *C, const int drawstep) +void WM_manipulatormap_draw( + wmManipulatorMap *mmap, const bContext *C, + const eWM_ManipulatorMapDrawStep drawstep) { ListBase draw_manipulators = {NULL}; @@ -317,9 +420,9 @@ void WM_manipulatormap_draw(wmManipulatorMap *mmap, const bContext *C, const int BLI_assert(BLI_listbase_is_empty(&draw_manipulators)); } -static void manipulator_find_active_3D_loop(const bContext *C, ListBase *visible_manipulators) +static void manipulator_draw_select_3D_loop(const bContext *C, ListBase *visible_manipulators) { - int selectionbase = 0; + int select_id = 0; wmManipulator *mpr; /* TODO(campbell): this depends on depth buffer being written to, currently broken for the 3D view. */ @@ -327,7 +430,7 @@ static void manipulator_find_active_3D_loop(const bContext *C, ListBase *visible for (LinkData *link = visible_manipulators->first; link; link = link->next) { mpr = link->data; - + bool is_depth = (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_DEPTH_3D) != 0; if (is_depth == is_depth_prev) { /* pass */ @@ -344,10 +447,10 @@ static void manipulator_find_active_3D_loop(const bContext *C, ListBase *visible /* pass the selection id shifted by 8 bits. Last 8 bits are used for selected manipulator part id */ - mpr->type->draw_select(C, mpr, selectionbase << 8); + mpr->type->draw_select(C, mpr, select_id << 8); - selectionbase++; + select_id++; } if (is_depth_prev) { @@ -357,7 +460,7 @@ static void manipulator_find_active_3D_loop(const bContext *C, ListBase *visible static int manipulator_find_intersected_3d_intern( ListBase *visible_manipulators, const bContext *C, const int co[2], - const float hotspot) + const int hotspot) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); @@ -368,31 +471,30 @@ static int manipulator_find_intersected_3d_intern( short hits; const bool do_passes = GPU_select_query_check_active(); - rect.xmin = co[0] - hotspot; - rect.xmax = co[0] + hotspot; - rect.ymin = co[1] - hotspot; - rect.ymax = co[1] + hotspot; + BLI_rcti_init_pt_radius(&rect, co, hotspot); - ED_view3d_draw_setup_view(CTX_wm_window(C), CTX_data_scene(C), ar, v3d, NULL, NULL, &rect); + ED_view3d_draw_setup_view(CTX_wm_window(C), C, CTX_data_scene(C), ar, v3d, NULL, NULL, &rect); if (do_passes) GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_FIRST_PASS, 0); else GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_ALL, 0); /* do the drawing */ - manipulator_find_active_3D_loop(C, visible_manipulators); + manipulator_draw_select_3D_loop(C, visible_manipulators); hits = GPU_select_end(); if (do_passes && (hits > 0)) { GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits); - manipulator_find_active_3D_loop(C, visible_manipulators); + manipulator_draw_select_3D_loop(C, visible_manipulators); GPU_select_end(); } - ED_view3d_draw_setup_view(CTX_wm_window(C), CTX_data_scene(C), ar, v3d, NULL, NULL, NULL); + ED_view3d_draw_setup_view(CTX_wm_window(C), C, CTX_data_scene(C), ar, v3d, NULL, NULL, NULL); - return hits > 0 ? buffer[3] : -1; + const GLuint *hit_near = GPU_select_buffer_near(buffer, hits); + + return hit_near ? hit_near[3] : -1; } /** @@ -403,26 +505,39 @@ static wmManipulator *manipulator_find_intersected_3d( int *r_part) { wmManipulator *result = NULL; - const float hotspot = 14.0f; - int ret; + int hit = -1; + + int hotspot_radii[] = { + 3 * U.pixelsize, +#if 0 /* We may want to enable when selection doesn't run on mousemove! */ + 7 * U.pixelsize, +#endif + }; *r_part = 0; /* set up view matrices */ view3d_operator_needs_opengl(C); - ret = manipulator_find_intersected_3d_intern(visible_manipulators, C, co, 0.5f * hotspot); - - if (ret != -1) { - LinkData *link; - int retsec; - retsec = manipulator_find_intersected_3d_intern(visible_manipulators, C, co, 0.2f * hotspot); + hit = -1; - if (retsec != -1) - ret = retsec; + for (int i = 0; i < ARRAY_SIZE(hotspot_radii); i++) { + hit = manipulator_find_intersected_3d_intern(visible_manipulators, C, co, hotspot_radii[i]); + if (hit != -1) { + break; + } + } - link = BLI_findlink(visible_manipulators, ret >> 8); - *r_part = ret & 255; - result = link->data; + if (hit != -1) { + LinkData *link = BLI_findlink(visible_manipulators, hit >> 8); + if (link != NULL) { + *r_part = hit & 255; + result = link->data; + } + else { + /* All manipulators should use selection ID they're given as part of the callback, + * if they don't it will attempt tp lookup non-existing index. */ + BLI_assert(0); + } } return result; @@ -442,25 +557,54 @@ wmManipulator *wm_manipulatormap_highlight_find( for (wmManipulatorGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) { if (wm_manipulatorgroup_is_visible(mgroup, C)) { if (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) { + if ((mmap->update_flag[WM_MANIPULATORMAP_DRAWSTEP_3D] & MANIPULATORMAP_IS_REFRESH_CALLBACK) && + mgroup->type->refresh) + { + mgroup->type->refresh(C, mgroup); + /* cleared below */ + } wm_manipulatorgroup_intersectable_manipulators_to_list(mgroup, &visible_3d_manipulators); } - else if ((mpr = wm_manipulatorgroup_find_intersected_mainpulator(mgroup, C, event, r_part))) { - break; + else { + if ((mmap->update_flag[WM_MANIPULATORMAP_DRAWSTEP_2D] & MANIPULATORMAP_IS_REFRESH_CALLBACK) && + mgroup->type->refresh) + { + mgroup->type->refresh(C, mgroup); + /* cleared below */ + } + + if ((mpr = wm_manipulatorgroup_find_intersected_mainpulator(mgroup, C, event, r_part))) { + break; + } } } } if (!BLI_listbase_is_empty(&visible_3d_manipulators)) { - mpr = manipulator_find_intersected_3d(C, event->mval, &visible_3d_manipulators, r_part); + /* 2D manipulators get priority. */ + if (mpr == NULL) { + mpr = manipulator_find_intersected_3d(C, event->mval, &visible_3d_manipulators, r_part); + } BLI_freelistN(&visible_3d_manipulators); } + mmap->update_flag[WM_MANIPULATORMAP_DRAWSTEP_3D] &= ~MANIPULATORMAP_IS_REFRESH_CALLBACK; + mmap->update_flag[WM_MANIPULATORMAP_DRAWSTEP_2D] &= ~MANIPULATORMAP_IS_REFRESH_CALLBACK; + return mpr; } void WM_manipulatormap_add_handlers(ARegion *ar, wmManipulatorMap *mmap) { - wmEventHandler *handler = MEM_callocN(sizeof(wmEventHandler), "manipulator handler"); + wmEventHandler *handler; + + for (handler = ar->handlers.first; handler; handler = handler->next) { + if (handler->manipulator_map == mmap) { + return; + } + } + + handler = MEM_callocN(sizeof(wmEventHandler), "manipulator handler"); BLI_assert(mmap == ar->manipulator_map); handler->manipulator_map = mmap; @@ -478,7 +622,7 @@ void wm_manipulatormaps_handled_modal_update( } wmManipulatorMap *mmap = handler->op_region->manipulator_map; - wmManipulator *mpr = wm_manipulatormap_active_get(mmap); + wmManipulator *mpr = wm_manipulatormap_modal_get(mmap); ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); @@ -500,7 +644,7 @@ void wm_manipulatormaps_handled_modal_update( /* operator not running anymore */ else { wm_manipulatormap_highlight_set(mmap, C, NULL, 0); - wm_manipulatormap_active_set(mmap, C, event, NULL); + wm_manipulatormap_modal_set(mmap, C, event, NULL); } /* restore the area */ @@ -512,16 +656,19 @@ void wm_manipulatormaps_handled_modal_update( * Deselect all selected manipulators in \a mmap. * \return if selection has changed. */ -bool wm_manipulatormap_deselect_all(wmManipulatorMap *mmap, wmManipulator ***sel) +bool wm_manipulatormap_deselect_all(wmManipulatorMap *mmap) { - if (*sel == NULL || mmap->mmap_context.selected_len == 0) + wmManipulatorMapSelectState *msel = &mmap->mmap_context.select; + + if (msel->items == NULL || msel->len == 0) { return false; + } - for (int i = 0; i < mmap->mmap_context.selected_len; i++) { - (*sel)[i]->state &= ~WM_MANIPULATOR_STATE_SELECT; - (*sel)[i] = NULL; + for (int i = 0; i < msel->len; i++) { + wm_manipulator_select_set_ex(mmap, msel->items[i], false, false, true); } - wm_manipulatormap_selected_clear(mmap); + + wm_manipulatormap_select_array_clear(mmap); /* always return true, we already checked * if there's anything to deselect */ @@ -538,36 +685,28 @@ BLI_INLINE bool manipulator_selectable_poll(const wmManipulator *mpr, void *UNUS * \return if selection has changed. */ static bool wm_manipulatormap_select_all_intern( - bContext *C, wmManipulatorMap *mmap, wmManipulator ***sel, - const int action) + bContext *C, wmManipulatorMap *mmap) { + wmManipulatorMapSelectState *msel = &mmap->mmap_context.select; /* GHash is used here to avoid having to loop over all manipulators twice (once to * get tot_sel for allocating, once for actually selecting). Instead we collect * selectable manipulators in hash table and use this to get tot_sel and do selection */ GHash *hash = WM_manipulatormap_manipulator_hash_new(C, mmap, manipulator_selectable_poll, NULL, true); GHashIterator gh_iter; - int i, *selected_len = &mmap->mmap_context.selected_len; + int i; bool changed = false; - *selected_len = BLI_ghash_size(hash); - *sel = MEM_reallocN(*sel, sizeof(**sel) * (*selected_len)); + wm_manipulatormap_select_array_ensure_len_alloc(mmap, BLI_ghash_size(hash)); GHASH_ITER_INDEX (gh_iter, hash, i) { wmManipulator *mpr_iter = BLI_ghashIterator_getValue(&gh_iter); - - if ((mpr_iter->state & WM_MANIPULATOR_STATE_SELECT) == 0) { - changed = true; - } - mpr_iter->state |= WM_MANIPULATOR_STATE_SELECT; - if (mpr_iter->type->select) { - mpr_iter->type->select(C, mpr_iter, action); - } - (*sel)[i] = mpr_iter; - BLI_assert(i < (*selected_len)); + WM_manipulator_select_set(mmap, mpr_iter, true); } /* highlight first manipulator */ - wm_manipulatormap_highlight_set(mmap, C, (*sel)[0], (*sel)[0]->highlight_part); + wm_manipulatormap_highlight_set(mmap, C, msel->items[0], msel->items[0]->highlight_part); + + BLI_assert(BLI_ghash_size(hash) == msel->len); BLI_ghash_free(hash, NULL, NULL); return changed; @@ -581,15 +720,14 @@ static bool wm_manipulatormap_select_all_intern( */ bool WM_manipulatormap_select_all(bContext *C, wmManipulatorMap *mmap, const int action) { - wmManipulator ***sel = &mmap->mmap_context.selected; bool changed = false; switch (action) { case SEL_SELECT: - changed = wm_manipulatormap_select_all_intern(C, mmap, sel, action); + changed = wm_manipulatormap_select_all_intern(C, mmap); break; case SEL_DESELECT: - changed = wm_manipulatormap_deselect_all(mmap, sel); + changed = wm_manipulatormap_deselect_all(mmap); break; default: BLI_assert(0); @@ -642,12 +780,10 @@ void wm_manipulatormap_handler_context(bContext *C, wmEventHandler *handler) bool WM_manipulatormap_cursor_set(const wmManipulatorMap *mmap, wmWindow *win) { - for (; mmap; mmap = mmap->next) { - wmManipulator *mpr = mmap->mmap_context.highlight; - if (mpr && mpr->type->cursor_get) { - WM_cursor_set(win, mpr->type->cursor_get(mpr)); - return true; - } + wmManipulator *mpr = mmap->mmap_context.highlight; + if (mpr && mpr->type->cursor_get) { + WM_cursor_set(win, mpr->type->cursor_get(mpr)); + return true; } return false; @@ -695,12 +831,12 @@ wmManipulator *wm_manipulatormap_highlight_get(wmManipulatorMap *mmap) return mmap->mmap_context.highlight; } -void wm_manipulatormap_active_set( +void wm_manipulatormap_modal_set( wmManipulatorMap *mmap, bContext *C, const wmEvent *event, wmManipulator *mpr) { if (mpr && C) { - mpr->state |= WM_MANIPULATOR_STATE_ACTIVE; - mmap->mmap_context.active = mpr; + mpr->state |= WM_MANIPULATOR_STATE_MODAL; + mmap->mmap_context.modal = mpr; if (mpr->op_data.type) { /* first activate the manipulator itself */ @@ -713,9 +849,8 @@ void wm_manipulatormap_active_set( WM_operator_name_call_ptr(C, mpr->op_data.type, WM_OP_INVOKE_DEFAULT, &mpr->op_data.ptr); /* we failed to hook the manipulator to the operator handler or operator was cancelled, return */ - if (!mmap->mmap_context.active) { - mpr->state &= ~WM_MANIPULATOR_STATE_ACTIVE; - /* first activate the manipulator itself */ + if (!mmap->mmap_context.modal) { + mpr->state &= ~WM_MANIPULATOR_STATE_MODAL; MEM_SAFE_FREE(mpr->interaction_data); } return; @@ -730,15 +865,14 @@ void wm_manipulatormap_active_set( WM_cursor_grab_enable(CTX_wm_window(C), true, true, NULL); } else { - mpr = mmap->mmap_context.active; + mpr = mmap->mmap_context.modal; /* deactivate, manipulator but first take care of some stuff */ if (mpr) { - mpr->state &= ~WM_MANIPULATOR_STATE_ACTIVE; - /* first activate the manipulator itself */ + mpr->state &= ~WM_MANIPULATOR_STATE_MODAL; MEM_SAFE_FREE(mpr->interaction_data); } - mmap->mmap_context.active = NULL; + mmap->mmap_context.modal = NULL; if (C) { WM_cursor_grab_disable(CTX_wm_window(C), NULL); @@ -748,9 +882,20 @@ void wm_manipulatormap_active_set( } } -wmManipulator *wm_manipulatormap_active_get(wmManipulatorMap *mmap) +wmManipulator *wm_manipulatormap_modal_get(wmManipulatorMap *mmap) { - return mmap->mmap_context.active; + return mmap->mmap_context.modal; +} + +wmManipulator **wm_manipulatormap_selected_get(wmManipulatorMap *mmap, int *r_selected_len) +{ + *r_selected_len = mmap->mmap_context.select.len; + return mmap->mmap_context.select.items; +} + +ListBase *wm_manipulatormap_groups_get(wmManipulatorMap *mmap) +{ + return &mmap->groups; } /** \} */ /* wmManipulatorMap */ @@ -837,8 +982,8 @@ void WM_manipulatorconfig_update_tag_init( wmManipulatorMapType *mmap_type, wmManipulatorGroupType *wgt) { /* tag for update on next use */ - mmap_type->type_update_flag |= WM_MANIPULATORMAPTYPE_UPDATE_INIT; - wgt->type_update_flag |= WM_MANIPULATORMAPTYPE_UPDATE_INIT; + mmap_type->type_update_flag |= (WM_MANIPULATORMAPTYPE_UPDATE_INIT | WM_MANIPULATORMAPTYPE_KEYMAP_INIT); + wgt->type_update_flag |= (WM_MANIPULATORMAPTYPE_UPDATE_INIT | WM_MANIPULATORMAPTYPE_KEYMAP_INIT); wm_mmap_type_update_flag |= WM_MANIPULATORMAPTYPE_GLOBAL_UPDATE_INIT; } @@ -890,14 +1035,22 @@ void WM_manipulatorconfig_update(struct Main *bmain) mmap_type; mmap_type = mmap_type->next) { - if (mmap_type->type_update_flag & WM_MANIPULATORMAPTYPE_UPDATE_INIT) { - mmap_type->type_update_flag &= ~WM_MANIPULATORMAPTYPE_UPDATE_INIT; + const uchar type_update_all = WM_MANIPULATORMAPTYPE_UPDATE_INIT | WM_MANIPULATORMAPTYPE_KEYMAP_INIT; + if (mmap_type->type_update_flag & type_update_all) { + mmap_type->type_update_flag &= ~type_update_all; for (wmManipulatorGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first; wgt_ref; wgt_ref = wgt_ref->next) { - wgt_ref->type->type_update_flag &= ~WM_MANIPULATORMAPTYPE_UPDATE_INIT; - WM_manipulatormaptype_group_init_runtime(bmain, mmap_type, wgt_ref->type); + if (wgt_ref->type->type_update_flag & WM_MANIPULATORMAPTYPE_KEYMAP_INIT) { + WM_manipulatormaptype_group_init_runtime_keymap(bmain, wgt_ref->type); + wgt_ref->type->type_update_flag &= ~WM_MANIPULATORMAPTYPE_KEYMAP_INIT; + } + + if (wgt_ref->type->type_update_flag & WM_MANIPULATORMAPTYPE_UPDATE_INIT) { + WM_manipulatormaptype_group_init_runtime(bmain, mmap_type, wgt_ref->type); + wgt_ref->type->type_update_flag &= ~WM_MANIPULATORMAPTYPE_UPDATE_INIT; + } } } } diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c index fcf7b2c986f..50e1d82a0fc 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c @@ -227,17 +227,33 @@ void WM_manipulator_target_property_value_set_array( RNA_property_update(C, &mpr_prop->ptr, mpr_prop->prop); } -void WM_manipulator_target_property_range_get( +bool WM_manipulator_target_property_range_get( const wmManipulator *mpr, wmManipulatorProperty *mpr_prop, float range[2]) { - if (mpr_prop->custom_func.range_get_fn) { - mpr_prop->custom_func.range_get_fn(mpr, mpr_prop, range); - return; + if (mpr_prop->custom_func.value_get_fn) { + if (mpr_prop->custom_func.range_get_fn) { + mpr_prop->custom_func.range_get_fn(mpr, mpr_prop, range); + return true; + } + else{ + return false; + + } } float step, precision; RNA_property_float_ui_range(&mpr_prop->ptr, mpr_prop->prop, &range[0], &range[1], &step, &precision); + return true; +} + +int WM_manipulator_target_property_array_length( + const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop) +{ + if (mpr_prop->custom_func.value_get_fn) { + return mpr_prop->type->array_length; + } + return RNA_property_array_length(&mpr_prop->ptr, mpr_prop->prop); } /** \} */ diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c index 7dabc70d69d..18265319024 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c @@ -28,6 +28,11 @@ #include "BLI_string.h" #include "BLI_string_utils.h" +#include "BKE_main.h" + +#include "DNA_screen_types.h" +#include "DNA_space_types.h" + #include "MEM_guardedalloc.h" #include "RNA_access.h" @@ -36,6 +41,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_screen.h" + /* only for own init/exit calls (wm_manipulatortype_init/wm_manipulatortype_free) */ #include "wm.h" @@ -123,16 +130,50 @@ static void manipulatortype_free(wmManipulatorType *wt) MEM_freeN(wt); } -void WM_manipulatortype_remove_ptr(wmManipulatorType *wt) +/** + * \param C: May be NULL. + */ +static void manipulatortype_unlink( + bContext *C, Main *bmain, wmManipulatorType *wt) +{ + /* Free instances. */ + for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) { + for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; + for (ARegion *ar = lb->first; ar; ar = ar->next) { + wmManipulatorMap *mmap = ar->manipulator_map; + if (mmap) { + wmManipulatorGroup *mgroup; + for (mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) { + for (wmManipulator *mpr = mgroup->manipulators.first, *mpr_next; mpr; mpr = mpr_next) { + mpr_next = mpr->next; + BLI_assert(mgroup->parent_mmap == mmap); + if (mpr->type == wt) { + WM_manipulator_unlink(&mgroup->manipulators, mgroup->parent_mmap, mpr, C); + ED_region_tag_redraw(ar); + } + } + } + } + } + } + } + } +} + +void WM_manipulatortype_remove_ptr(bContext *C, Main *bmain, wmManipulatorType *wt) { BLI_assert(wt == WM_manipulatortype_find(wt->idname, false)); BLI_ghash_remove(global_manipulatortype_hash, wt->idname, NULL, NULL); + manipulatortype_unlink(C, bmain, wt); + manipulatortype_free(wt); } -bool WM_manipulatortype_remove(const char *idname) +bool WM_manipulatortype_remove(bContext *C, Main *bmain, const char *idname) { wmManipulatorType *wt = BLI_ghash_lookup(global_manipulatortype_hash, idname); @@ -140,7 +181,7 @@ bool WM_manipulatortype_remove(const char *idname) return false; } - WM_manipulatortype_remove_ptr(wt); + WM_manipulatortype_remove_ptr(C, bmain, wt); return true; } diff --git a/source/blender/windowmanager/manipulators/wm_manipulator_fn.h b/source/blender/windowmanager/manipulators/wm_manipulator_fn.h index ae72e04e1c3..a9dd9b1f114 100644 --- a/source/blender/windowmanager/manipulators/wm_manipulator_fn.h +++ b/source/blender/windowmanager/manipulators/wm_manipulator_fn.h @@ -50,13 +50,13 @@ typedef void (*wmManipulatorFnSetup)(struct wmManipulator *); typedef void (*wmManipulatorFnDraw)(const struct bContext *, struct wmManipulator *); typedef void (*wmManipulatorFnDrawSelect)(const struct bContext *, struct wmManipulator *, int); typedef int (*wmManipulatorFnTestSelect)(struct bContext *, struct wmManipulator *, const struct wmEvent *); -typedef void (*wmManipulatorFnModal)(struct bContext *, struct wmManipulator *, const struct wmEvent *, const int); +typedef void (*wmManipulatorFnModal)(struct bContext *, struct wmManipulator *, const struct wmEvent *, eWM_ManipulatorTweak); typedef void (*wmManipulatorFnPropertyUpdate)(struct wmManipulator *, struct wmManipulatorProperty *); typedef void (*wmManipulatorFnMatrixWorldGet)(struct wmManipulator *, float[4][4]); typedef void (*wmManipulatorFnInvoke)(struct bContext *, struct wmManipulator *, const struct wmEvent *); typedef void (*wmManipulatorFnExit)(struct bContext *, struct wmManipulator *, const bool); typedef int (*wmManipulatorFnCursorGet)(struct wmManipulator *); -typedef void (*wmManipulatorFnSelect)(struct bContext *, struct wmManipulator *, const int); +typedef void (*wmManipulatorFnSelectRefresh)(struct wmManipulator *); /* wmManipulatorProperty ('value' type defined by 'wmManipulatorProperty.data_type') */ typedef void (*wmManipulatorPropertyFnGet)( diff --git a/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h b/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h index 61489b6a730..cc1bf398764 100644 --- a/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h +++ b/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h @@ -61,6 +61,8 @@ void wm_manipulatorgrouptype_init(void); void MANIPULATORGROUP_OT_manipulator_select(struct wmOperatorType *ot); void MANIPULATORGROUP_OT_manipulator_tweak(struct wmOperatorType *ot); +bool wm_manipulatorgroup_is_any_selected(const struct wmManipulatorGroup *mgroup); + /* -------------------------------------------------------------------- */ /* wmManipulatorMap */ @@ -79,10 +81,12 @@ void wm_manipulatormap_highlight_set( struct wmManipulatorMap *mmap, const bContext *C, struct wmManipulator *mpr, int part); struct wmManipulator *wm_manipulatormap_highlight_get(struct wmManipulatorMap *mmap); -void wm_manipulatormap_active_set( +void wm_manipulatormap_modal_set( struct wmManipulatorMap *mmap, bContext *C, const struct wmEvent *event, struct wmManipulator *mpr); -struct wmManipulator *wm_manipulatormap_active_get(struct wmManipulatorMap *mmap); +struct wmManipulator *wm_manipulatormap_modal_get(struct wmManipulatorMap *mmap); +struct wmManipulator **wm_manipulatormap_selected_get(wmManipulatorMap *mmap, int *r_selected_len); +struct ListBase *wm_manipulatormap_groups_get(wmManipulatorMap *mmap); /* -------------------------------------------------------------------- */ /* wmManipulatorMapType */ diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index 2f7ebbc1def..abab7c55f44 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -52,7 +52,7 @@ typedef struct wmEventHandler { wmKeyMap *keymap; /* pointer to builtin/custom keymaps */ const rcti *bblocal, *bbwin; /* optional local and windowspace bb */ - /* modal operator handler and WM_HANDLER_FILESELECT */ + /* modal operator handler */ wmOperator *op; /* for derived/modal handlers */ struct ScrArea *op_area; /* for derived/modal handlers */ struct ARegion *op_region; /* for derived/modal handlers */ diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 13f567762b5..2ead8db0146 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -195,6 +195,7 @@ struct wmManipulatorMap; #include "../blender/render/extern/include/RE_shader_ext.h" #include "../blender/draw/DRW_engine.h" #include "../blender/windowmanager/WM_api.h" +#include "../blender/windowmanager/WM_types.h" /* -------------------------------------------------------------------- */ @@ -367,24 +368,25 @@ void BPY_RNA_manipulator_wrapper(struct wmManipulatorType *wgt, void *userdata) PointerRNA *WM_manipulator_set_operator(struct wmManipulator *mpr, struct wmOperatorType *ot, struct IDProperty *properties) RET_NULL const struct wmManipulatorPropertyType *WM_manipulatortype_target_property_find(const struct wmManipulatorType *wt, const char *idname) RET_NULL const struct wmManipulatorType *WM_manipulatortype_find(const char *idname, bool quiet) RET_NULL -struct wmManipulator *WM_manipulator_new_ptr(const struct wmManipulatorType *wt, struct wmManipulatorGroup *mgroup, const char *name, struct PointerRNA *properties) RET_NULL +struct wmManipulator *WM_manipulator_new_ptr(const struct wmManipulatorType *wt, struct wmManipulatorGroup *mgroup, struct PointerRNA *properties) RET_NULL struct wmManipulatorGroupType *WM_manipulatorgrouptype_append_ptr(void (*mnpfunc)(struct wmManipulatorGroupType *, void *), void *userdata) RET_NULL struct wmManipulatorGroupType *WM_manipulatorgrouptype_find(const char *idname, bool quiet) RET_NULL -void WM_manipulator_free(ListBase *manipulatorlist, struct wmManipulatorMap *mmap, struct wmManipulator *mpr, struct bContext *C) RET_NONE +void WM_manipulator_unlink(ListBase *manipulatorlist, struct wmManipulatorMap *mmap, struct wmManipulator *mpr, struct bContext *C) RET_NONE void WM_manipulator_group_add_ptr(struct wmManipulatorGroupType *wgt) RET_NONE void WM_manipulator_group_add_ptr_ex(struct wmManipulatorGroupType *wgt, struct wmManipulatorMapType *mmap_type) RET_NONE void WM_manipulator_group_remove_ptr(struct Main *bmain, struct wmManipulatorGroupType *wgt) RET_NONE void WM_manipulator_name_set(struct wmManipulatorGroup *mgroup, struct wmManipulator *mpr, const char *name) RET_NONE +bool WM_manipulator_select_set(struct wmManipulatorMap *mmap, struct wmManipulator *mpr, bool select) RET_ZERO void WM_manipulator_target_property_def_rna_ptr(struct wmManipulator *mpr, const struct wmManipulatorPropertyType *mpr_prop_type, struct PointerRNA *ptr, struct PropertyRNA *prop, int index) RET_NONE void WM_manipulatorgrouptype_remove_ptr(struct wmManipulatorGroupType *wt) RET_NONE void WM_manipulatormaptype_group_unlink(struct bContext *C, struct Main *bmain, struct wmManipulatorMapType *mmap_type, const struct wmManipulatorGroupType *wgt) RET_NONE void WM_manipulatortype_append_ptr(void (*mnpfunc)(struct wmManipulatorType *, void *), void *userdata) RET_NONE -void WM_manipulatortype_remove_ptr(struct wmManipulatorType *wt) RET_NONE +void WM_manipulatortype_remove_ptr(struct bContext *C, struct Main *bmain, struct wmManipulatorType *wt) RET_NONE void ED_manipulator_draw_preset_box(const struct wmManipulator *mpr, float mat[4][4], int select_id) RET_NONE void ED_manipulator_draw_preset_arrow(const struct wmManipulator *mpr, float mat[4][4], int axis, int select_id) RET_NONE void ED_manipulator_draw_preset_circle(const struct wmManipulator *mpr, float mat[4][4], int axis, int select_id) RET_NONE -void ED_manipulator_draw_preset_facemap(const struct wmManipulator *mpr, struct Scene *scene, struct Object *ob, const int facemap, int select_id) RET_NONE +void ED_manipulator_draw_preset_facemap(const struct bContext *C, const struct wmManipulator *mpr, struct Scene *scene, struct Object *ob, const int facemap, int select_id) RET_NONE struct wmManipulatorMapType *WM_manipulatormaptype_find(const struct wmManipulatorMapType_Params *wmap_params) RET_NULL struct wmManipulatorMapType *WM_manipulatormaptype_ensure(const struct wmManipulatorMapType_Params *wmap_params) RET_NULL @@ -469,7 +471,7 @@ char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry) RET_NULL void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name) RET_NONE struct PTCacheEdit *PE_get_current(struct Scene *scene, struct SceneLayer *sl, struct Object *ob) RET_NULL -void PE_current_changed(struct Scene *scene, struct Object *ob) RET_NONE +void PE_current_changed(const struct bContext *C, struct Scene *scene, struct Object *ob) RET_NONE /* rna keymap */ struct wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap) RET_NULL @@ -536,7 +538,7 @@ void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist struct BGpic *ED_view3D_background_image_new(struct View3D *v3d) RET_NULL void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic) RET_NONE void ED_view3D_background_image_clear(struct View3D *v3d) RET_NONE -void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4], const struct rcti *rect) RET_NONE +void ED_view3d_update_viewmat(struct EvaluationContext *eval_ctx, struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4], const struct rcti *rect) RET_NONE float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit) RET_ZERO void ED_view3d_shade_update(struct Main *bmain, struct Scene *scene, struct View3D *v3d, struct ScrArea *sa) RET_NONE void ED_node_shader_default(const struct bContext *C, struct ID *id) RET_NONE @@ -609,6 +611,7 @@ SnapObjectContext *ED_transform_snap_object_context_create_view3d( const struct ARegion *ar, const struct View3D *v3d) RET_NULL void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx) RET_NONE bool ED_transform_snap_object_project_ray_ex( + const struct bContext *C, struct SnapObjectContext *sctx, const struct SnapObjectParams *params, const float ray_start[3], const float ray_normal[3], float *ray_depth, @@ -751,14 +754,15 @@ void RE_engine_update_memory_stats(struct RenderEngine *engine, float mem_used, struct RenderEngine *RE_engine_create(struct RenderEngineType *type) RET_NULL void RE_engine_frame_set(struct RenderEngine *engine, int frame, float subframe) RET_NONE void RE_FreePersistentData(void) RET_NONE -void RE_point_density_cache(struct Scene *scene, struct PointDensity *pd, const bool use_render_params) RET_NONE -void RE_point_density_minmax(struct Scene *scene, struct PointDensity *pd, const bool use_render_params, float r_min[3], float r_max[3]) RET_NONE -void RE_point_density_sample(struct Scene *scene, struct PointDensity *pd, const int resolution, const bool use_render_params, float *values) RET_NONE +void RE_point_density_cache(struct Scene *scene, struct SceneLayer *sl, struct PointDensity *pd, const bool use_render_params) RET_NONE +void RE_point_density_minmax(struct Scene *scene, struct SceneLayer *sl, struct PointDensity *pd, const bool use_render_params, float r_min[3], float r_max[3]) RET_NONE +void RE_point_density_sample(struct Scene *scene, struct SceneLayer *sl, struct PointDensity *pd, const int resolution, const bool use_render_params, float *values) RET_NONE void RE_point_density_free(struct PointDensity *pd) RET_NONE void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) RET_NONE void RE_FreeAllPersistentData(void) RET_NONE float RE_fresnel_dielectric(float incoming[3], float normal[3], float eta) RET_ZERO void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl, const char *name, int channels, const char *chanid, int type) RET_NONE +struct SceneLayer *RE_engine_get_scene_layer(struct Render *re) RET_NULL /* Draw */ void OBJECT_collection_settings_create(struct IDProperty *properties) RET_NONE @@ -807,7 +811,8 @@ int UI_pie_menu_invoke_from_operator_enum(struct bContext *C, const char *title, const char *propname, const struct wmEvent *event) RET_ZERO /* RNA COLLADA dependency */ -int collada_export(struct Scene *sce, +int collada_export(struct EvaluationContext *eval_ctx, + struct Scene *sce, struct SceneLayer *scene_layer, const char *filepath, int apply_modifiers, @@ -841,6 +846,7 @@ void BPY_RNA_operator_wrapper(struct wmOperatorType *ot, void *userdata) RET_NON void BPY_RNA_operator_macro_wrapper(struct wmOperatorType *ot, void *userdata) RET_NONE void BPY_text_free_code(struct Text *text) RET_NONE void BPY_id_release(struct ID *id) RET_NONE +void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr) RET_NONE int BPY_context_member_get(struct bContext *C, const char *member, struct bContextDataResult *result) RET_ZERO void BPY_pyconstraint_target(struct bPythonConstraint *con, struct bConstraintTarget *ct) RET_NONE float BPY_driver_exec(PathResolvedRNA *anim_rna, struct ChannelDriver *driver, const float evaltime) RET_ZERO /* might need this one! */ diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index 1f6687c2b67..049fd49cab9 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -470,6 +470,8 @@ bool BL_ArmatureObject::UnlinkObject(SCA_IObject* clientobj) void BL_ArmatureObject::ApplyPose() { + /* TODO: This doesn't work currently because of eval_ctx. */ +#if 0 m_armpose = m_objArma->pose; m_objArma->pose = m_pose; // in the GE, we use ctime to store the timestep @@ -492,6 +494,7 @@ void BL_ArmatureObject::ApplyPose() } m_lastapplyframe = m_lastframe; } +#endif } void BL_ArmatureObject::RestorePose() diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 6667e6a44c2..71ac6f4fdb1 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -45,7 +45,9 @@ * This workaround will make sure that curve_cache for curves * is up-to-date. */ -#define THREADED_DAG_WORKAROUND + +/* TODO: Disabled for now, because of eval_ctx. */ +//#define THREADED_DAG_WORKAROUND #include <math.h> #include <vector> diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp index b40fb7a9f47..3be2c1aff43 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.cpp +++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp @@ -133,6 +133,8 @@ bool BL_ModifierDeformer::HasArmatureDeformer(Object *ob) // return a deformed mesh that supports mapping (with a valid CD_ORIGINDEX layer) struct DerivedMesh* BL_ModifierDeformer::GetPhysicsMesh() { + /* TODO: This doesn't work currently because of eval_ctx. */ +#if 0 /* we need to compute the deformed mesh taking into account the current * shape and skin deformers, we cannot just call mesh_create_derived_physics() * because that would use the m_transvers already deformed previously by BL_ModifierDeformer::Update(), @@ -152,10 +154,14 @@ struct DerivedMesh* BL_ModifierDeformer::GetPhysicsMesh() /* m_transverts is correct here (takes into account deform only modifiers) */ /* the derived mesh returned by this function must be released by the caller !!! */ return dm; +#endif + return NULL; } bool BL_ModifierDeformer::Update(void) { + /* TODO: This doesn't work currently because of eval_ctx. */ +#if 0 bool bShapeUpdate = BL_ShapeDeformer::Update(); if (bShapeUpdate || m_lastModifierUpdate != m_gameobj->GetLastFrame()) { @@ -208,6 +214,8 @@ bool BL_ModifierDeformer::Update(void) } } return bShapeUpdate; +#endif + return false; } bool BL_ModifierDeformer::Apply(RAS_IPolyMaterial *mat) diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt index 05071f59707..b9eec74f6f4 100644 --- a/source/gameengine/GameLogic/CMakeLists.txt +++ b/source/gameengine/GameLogic/CMakeLists.txt @@ -139,6 +139,9 @@ if(WITH_SDL) if(WITH_GHOST_SDL) add_definitions(-DWITH_GHOST_SDL) endif() + if(WITH_SDL_DYNLOAD) + add_definitions(-DWITH_SDL_DYNLOAD) + endif() endif() blender_add_lib(ge_logic "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp index 1a66b2aee52..9f532527a80 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp @@ -38,7 +38,11 @@ #include "BLI_path_util.h" #ifdef WITH_SDL -# define SDL_CHECK(x) ((x) != (void *)0) +# ifdef WITH_SDL_DYNLOAD +# define SDL_CHECK(x) ((x) != (void *)0) +# else +# define SDL_CHECK(x) true +# endif #endif SCA_Joystick::SCA_Joystick(short int index) diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp index fd3d713b3d2..1dee1de9de2 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp @@ -82,9 +82,11 @@ void SCA_Joystick::HandleEvents(void) { SDL_Event sdl_event; +#ifdef WITH_SDL_DYNLOAD if (SDL_PollEvent == (void*)0) { return; } +#endif int i; for (i=0; i<m_joynum; i++) { /* could use JOYINDEX_MAX but no reason to */ diff --git a/source/gameengine/Ketsji/KX_FontObject.cpp b/source/gameengine/Ketsji/KX_FontObject.cpp index 364f8d4bfc6..91e8e4fd42b 100644 --- a/source/gameengine/Ketsji/KX_FontObject.cpp +++ b/source/gameengine/Ketsji/KX_FontObject.cpp @@ -281,7 +281,7 @@ int KX_FontObject::pyattr_set_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrd KX_FontObject* self = static_cast<KX_FontObject*>(self_v); if (!PyUnicode_Check(value)) return PY_SET_ATTR_FAIL; - char* chars = _PyUnicode_AsString(value); + const char *chars = _PyUnicode_AsString(value); /* Allow for some logic brick control */ CValue* tprop = self->GetProperty("Text"); diff --git a/source/gameengine/Ketsji/KX_NavMeshObject.cpp b/source/gameengine/Ketsji/KX_NavMeshObject.cpp index 5beda2e038a..83accb1d7a5 100644 --- a/source/gameengine/Ketsji/KX_NavMeshObject.cpp +++ b/source/gameengine/Ketsji/KX_NavMeshObject.cpp @@ -113,6 +113,8 @@ bool KX_NavMeshObject::BuildVertIndArrays(float *&vertices, int& nverts, float *&dvertices, int &ndvertsuniq, unsigned short *&dtris, int& ndtris, int &vertsPerPoly) { + /* TODO: This doesn't work currently because of eval_ctx. */ +#if 0 DerivedMesh* dm = mesh_create_derived_no_virtual(GetScene()->GetBlenderScene(), GetBlenderObject(), NULL, CD_MASK_MESH); CustomData *pdata = dm->getPolyDataLayout(dm); @@ -280,6 +282,8 @@ bool KX_NavMeshObject::BuildVertIndArrays(float *&vertices, int& nverts, dm->release(dm); return true; +#endif + return false; } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 80c399fb256..d1c3162f752 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -770,7 +770,6 @@ static RAS_MeshSlot *current_ms; static RAS_MeshObject *current_mesh; static int current_blmat_nr; static GPUVertexAttribs current_gpu_attribs; -static Image *current_image; static int CheckMaterialDM(int matnr, void *attribs) { // only draw the current material |