diff options
author | Sergey Sharybin <sergey@blender.org> | 2022-01-05 11:53:48 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey@blender.org> | 2022-01-25 16:43:44 +0300 |
commit | 196da819ba4cf553c76468a091966f33081efb08 (patch) | |
tree | 0d289d01aa832fd7a629df02d106daffdb64a462 /source | |
parent | 31296f6f9d67570920c143be24b26e28f10a0ebb (diff) |
Python: Expose crazyspace correction functionality via RNA
Allows to perform correction of coordinate delta/displacement in a
similar way of how sculpt mode handles sculpting on a deformed mesh.
An example of usecase of this is allowing riggers and sciprters to
improve corrective shapekey workflow.
The usage consists of pre-processing and access. For example:
object.crazyspace_eval(depsgraph, scene)
# When we have a difference between two vertices and want to convert
# it to a space to be stored, say, in shapekey:
delta_in_orig_space = rigged_ob.crazyspace_displacement_to_original(
vertex_index=i, displacement=delta)
# The reverse of above.
delta_in_deformed_space = rigged_ob.crazyspace_displacement_to_deformed(
vertex_index=i, displacement=delta)
object.crazyspace_eval_clear()
Fuller explanation with actual usecases and studio examples are written in
the comment:
https://developer.blender.org/D13892#368898
Differential Revision: https://developer.blender.org/D13892
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_crazyspace.h | 27 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/crazyspace.c | 83 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.cc | 6 | ||||
-rw-r--r-- | source/blender/editors/object/object_shapekey.c | 3 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_types.h | 6 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object_api.c | 80 |
6 files changed, 205 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_crazyspace.h b/source/blender/blenkernel/BKE_crazyspace.h index c00e397f552..61c5b2ae29e 100644 --- a/source/blender/blenkernel/BKE_crazyspace.h +++ b/source/blender/blenkernel/BKE_crazyspace.h @@ -26,10 +26,12 @@ #ifdef __cplusplus extern "C" { #endif + struct BMEditMesh; struct Depsgraph; struct Mesh; struct Object; +struct ReportList; struct Scene; /* crazyspace.c */ @@ -69,6 +71,31 @@ void BKE_crazyspace_build_sculpt(struct Depsgraph *depsgraph, float (**deformmats)[3][3], float (**deformcos)[3]); +/* -------------------------------------------------------------------- */ +/** \name Crazyspace API + * \{ */ + +void BKE_crazyspace_api_eval(struct Depsgraph *depsgraph, + struct Scene *scene, + struct Object *object, + struct ReportList *reports); + +void BKE_crazyspace_api_displacement_to_deformed(struct Object *object, + struct ReportList *reports, + int vertex_index, + float displacement[3], + float r_displacement_deformed[3]); + +void BKE_crazyspace_api_displacement_to_original(struct Object *object, + struct ReportList *reports, + int vertex_index, + float displacement_deformed[3], + float r_displacement[3]); + +void BKE_crazyspace_api_eval_clear(struct Object *object); + +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c index 9408b9190ae..573595b6f90 100644 --- a/source/blender/blenkernel/intern/crazyspace.c +++ b/source/blender/blenkernel/intern/crazyspace.c @@ -41,6 +41,7 @@ #include "BKE_mesh_wrapper.h" #include "BKE_modifier.h" #include "BKE_multires.h" +#include "BKE_report.h" #include "DEG_depsgraph_query.h" @@ -516,3 +517,85 @@ void BKE_crazyspace_build_sculpt(struct Depsgraph *depsgraph, } } } + +/* -------------------------------------------------------------------- */ +/** \name Crazyspace API + * \{ */ + +void BKE_crazyspace_api_eval(Depsgraph *depsgraph, + Scene *scene, + Object *object, + struct ReportList *reports) +{ + if (object->runtime.crazyspace_deform_imats != NULL || + object->runtime.crazyspace_deform_cos != NULL) { + return; + } + + if (object->type != OB_MESH) { + BKE_report(reports, + RPT_ERROR, + "Crazyspace transformation is only available for Mesh type of objects"); + return; + } + + const Mesh *mesh = (const Mesh *)object->data; + object->runtime.crazyspace_num_verts = mesh->totvert; + BKE_crazyspace_build_sculpt(depsgraph, + scene, + object, + &object->runtime.crazyspace_deform_imats, + &object->runtime.crazyspace_deform_cos); +} + +void BKE_crazyspace_api_displacement_to_deformed(struct Object *object, + struct ReportList *reports, + int vertex_index, + float displacement[3], + float r_displacement_deformed[3]) +{ + if (vertex_index < 0 || vertex_index >= object->runtime.crazyspace_num_verts) { + BKE_reportf(reports, + RPT_ERROR, + "Invalid vertex index %d (expected to be within 0 to %d range)", + vertex_index, + object->runtime.crazyspace_num_verts); + return; + } + + mul_v3_m3v3(r_displacement_deformed, + object->runtime.crazyspace_deform_imats[vertex_index], + displacement); +} + +void BKE_crazyspace_api_displacement_to_original(struct Object *object, + struct ReportList *reports, + int vertex_index, + float displacement_deformed[3], + float r_displacement[3]) +{ + if (vertex_index < 0 || vertex_index >= object->runtime.crazyspace_num_verts) { + BKE_reportf(reports, + RPT_ERROR, + "Invalid vertex index %d (expected to be within 0 to %d range))", + vertex_index, + object->runtime.crazyspace_num_verts); + return; + } + + float mat[3][3]; + if (!invert_m3_m3(mat, object->runtime.crazyspace_deform_imats[vertex_index])) { + copy_v3_v3(r_displacement, displacement_deformed); + return; + } + + mul_v3_m3v3(r_displacement, mat, displacement_deformed); +} + +void BKE_crazyspace_api_eval_clear(Object *object) +{ + MEM_SAFE_FREE(object->runtime.crazyspace_deform_imats); + MEM_SAFE_FREE(object->runtime.crazyspace_deform_cos); +} + +/** \} */ diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 3fa380d2519..ed0174bd592 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -87,6 +87,7 @@ #include "BKE_camera.h" #include "BKE_collection.h" #include "BKE_constraint.h" +#include "BKE_crazyspace.h" #include "BKE_curve.h" #include "BKE_deform.h" #include "BKE_displist.h" @@ -1881,6 +1882,8 @@ void BKE_object_free_derived_caches(Object *ob) BKE_object_to_curve_clear(ob); BKE_object_free_curve_cache(ob); + BKE_crazyspace_api_eval_clear(ob); + /* Clear grease pencil data. */ if (ob->runtime.gpd_eval != nullptr) { BKE_gpencil_eval_delete(ob->runtime.gpd_eval); @@ -5219,6 +5222,9 @@ void BKE_object_runtime_reset_on_copy(Object *object, const int UNUSED(flag)) runtime->object_as_temp_mesh = nullptr; runtime->object_as_temp_curve = nullptr; runtime->geometry_set_eval = nullptr; + + runtime->crazyspace_deform_imats = nullptr; + runtime->crazyspace_deform_cos = nullptr; } void BKE_object_runtime_free_data(Object *object) diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index fd649854d8f..a871ddea48c 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -43,13 +43,16 @@ #include "DNA_object_types.h" #include "BKE_context.h" +#include "BKE_crazyspace.h" #include "BKE_key.h" #include "BKE_lattice.h" #include "BKE_main.h" #include "BKE_object.h" +#include "BKE_report.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" #include "BLI_sys_types.h" /* for intptr_t support */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index f9ef4ba0000..602f968634e 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -216,6 +216,12 @@ typedef struct Object_Runtime { unsigned short local_collections_bits; short _pad2[3]; + + float (*crazyspace_deform_imats)[3][3]; + float (*crazyspace_deform_cos)[3]; + int crazyspace_num_verts; + + int _pad3[3]; } Object_Runtime; typedef struct ObjectLineArt { diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index ec20fa54a44..cc9f6454337 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -68,6 +68,7 @@ static const EnumPropertyItem space_items[] = { # include "BKE_bvhutils.h" # include "BKE_constraint.h" # include "BKE_context.h" +# include "BKE_crazyspace.h" # include "BKE_customdata.h" # include "BKE_global.h" # include "BKE_layer.h" @@ -379,6 +380,39 @@ static void rna_Object_camera_fit_coords( depsgraph, (const float(*)[3])cos, num_cos / 3, ob, co_ret, scale_ret); } +static void rna_Object_crazyspace_eval(Object *object, + ReportList *reports, + Depsgraph *depsgraph, + Scene *scene) +{ + BKE_crazyspace_api_eval(depsgraph, scene, object, reports); +} + +static void rna_Object_crazyspace_displacement_to_deformed(Object *object, + ReportList *reports, + const int vertex_index, + float displacement[3], + float r_displacement_deformed[3]) +{ + BKE_crazyspace_api_displacement_to_deformed( + object, reports, vertex_index, displacement, r_displacement_deformed); +} + +static void rna_Object_crazyspace_displacement_to_original(Object *object, + ReportList *reports, + const int vertex_index, + float displacement_deformed[3], + float r_displacement[3]) +{ + BKE_crazyspace_api_displacement_to_original( + object, reports, vertex_index, displacement_deformed, r_displacement); +} + +static void rna_Object_crazyspace_eval_clear(Object *object) +{ + BKE_crazyspace_api_eval_clear(object); +} + /* copied from Mesh_getFromObject and adapted to RNA interface */ static Mesh *rna_Object_to_mesh(Object *object, ReportList *reports, @@ -978,6 +1012,52 @@ void RNA_api_object(StructRNA *srna) parm, "", "The ortho scale to aim to be able to see all given points (if relevant)"); RNA_def_parameter_flags(parm, 0, PARM_OUTPUT); + /* Crazyspace access. */ + + func = RNA_def_function(srna, "crazyspace_eval", "rna_Object_crazyspace_eval"); + RNA_def_function_ui_description( + func, + "Compute orientation mapping between vertices of an original object and object with shape " + "keys and deforming modifiers applied." + "The evaluation is to be freed with the crazyspace_eval_free function"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_pointer( + func, "depsgraph", "Depsgraph", "Dependency Graph", "Evaluated dependency graph"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_pointer(func, "scene", "Scene", "Scene", "Scene of the object"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + + func = RNA_def_function(srna, + "crazyspace_displacement_to_deformed", + "rna_Object_crazyspace_displacement_to_deformed"); + RNA_def_function_ui_description( + func, "Convert displacement vector from non-deformed object space to deformed object space"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_property(func, "vertex_index", PROP_INT, PROP_NONE); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_property(func, "displacement", PROP_FLOAT, PROP_XYZ); + RNA_def_property_array(parm, 3); + parm = RNA_def_property(func, "displacement_deformed", PROP_FLOAT, PROP_XYZ); + RNA_def_property_array(parm, 3); + RNA_def_function_output(func, parm); + + func = RNA_def_function(srna, + "crazyspace_displacement_to_original", + "rna_Object_crazyspace_displacement_to_original"); + RNA_def_function_ui_description( + func, "Convert displacement vector from deformed object space to non-deformed object space"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_property(func, "vertex_index", PROP_INT, PROP_NONE); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_property(func, "displacement", PROP_FLOAT, PROP_XYZ); + RNA_def_property_array(parm, 3); + parm = RNA_def_property(func, "displacement_original", PROP_FLOAT, PROP_XYZ); + RNA_def_property_array(parm, 3); + RNA_def_function_output(func, parm); + + RNA_def_function(srna, "crazyspace_eval_clear", "rna_Object_crazyspace_eval_clear"); + RNA_def_function_ui_description(func, "Free evaluated state of crazyspace"); + /* mesh */ func = RNA_def_function(srna, "to_mesh", "rna_Object_to_mesh"); RNA_def_function_ui_description( |