diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_curve.h | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_displist.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_object.h | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve_convert.c | 81 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 24 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 20 |
7 files changed, 152 insertions, 9 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 881b93fe709..660e7c08062 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -338,6 +338,18 @@ void BKE_curve_deform_co(const struct Object *ob_curve, /** \} */ +/* curve_convert.c */ + +/* Create a new curve from the given object at its current state. This only works for curve and + * text objects, otherwise NULL is returned. + * + * If apply_modifiers is true and the object is a curve one, then spline deform modifiers are + * applied on the control points of the splines. + */ +struct Curve *BKE_curve_new_from_object(struct Object *object, + struct Depsgraph *depsgraph, + bool apply_modifiers); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 83adbf6f1fd..05e60d38487 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -112,6 +112,13 @@ void BKE_displist_make_mball_forRender(struct Depsgraph *depsgraph, struct Object *ob, struct ListBase *dispbase); +bool BKE_curve_calc_modifiers_pre(struct Depsgraph *depsgraph, + struct Scene *scene, + struct Object *ob, + struct ListBase *source_nurb, + struct ListBase *target_nurb, + const bool for_render); + bool BKE_displist_surfindex_get(DispList *dl, int a, int *b, int *p1, int *p2, int *p3, int *p4); void BKE_displist_fill(const struct ListBase *dispbase, struct ListBase *to, diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 904db053717..12c40e891c9 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -32,6 +32,7 @@ extern "C" { struct Base; struct BoundBox; +struct Curve; struct Depsgraph; struct GpencilModifierData; struct HookGpencilModifierData; @@ -424,6 +425,21 @@ struct Mesh *BKE_object_to_mesh(struct Depsgraph *depsgraph, void BKE_object_to_mesh_clear(struct Object *object); +/* This is an utility function for Python's object.to_curve(). + * The result is owned by the object. + * + * The curve will be freed when object is re-evaluated or is destroyed. It is possible to force + * clear memory used by this curve by calling BKE_object_to_curve_clear(). + * + * If apply_modifiers is true and the object is a curve one, then spline deform modifiers are + * applied on the curve control points. + */ +struct Curve *BKE_object_to_curve(struct Object *object, + struct Depsgraph *depsgraph, + bool apply_modifiers); + +void BKE_object_to_curve_clear(struct Object *object); + void BKE_object_check_uuids_unique_and_report(const struct Object *object); void BKE_object_modifiers_lib_link_common(void *userData, diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index f288bf9aabc..325744f4006 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -107,6 +107,7 @@ set(SRC intern/cryptomatte.cc intern/curve.c intern/curve_bevel.c + intern/curve_convert.c intern/curve_decimate.c intern/curve_deform.c intern/curveprofile.c diff --git a/source/blender/blenkernel/intern/curve_convert.c b/source/blender/blenkernel/intern/curve_convert.c new file mode 100644 index 00000000000..988ddb3bbc0 --- /dev/null +++ b/source/blender/blenkernel/intern/curve_convert.c @@ -0,0 +1,81 @@ +/* + * 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. + */ + +/** \file + * \ingroup bke + */ + +#include "DNA_curve_types.h" +#include "DNA_object_types.h" +#include "DNA_vfont_types.h" + +#include "BLI_utildefines.h" + +#include "BKE_curve.h" +#include "BKE_displist.h" +#include "BKE_font.h" +#include "BKE_lib_id.h" +#include "BKE_modifier.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +static Curve *curve_from_font_object(Object *object, Depsgraph *depsgraph) +{ + Curve *curve = (Curve *)object->data; + Curve *new_curve = (Curve *)BKE_id_copy_ex(NULL, &curve->id, NULL, LIB_ID_COPY_LOCALIZE); + + Object *evaluated_object = DEG_get_evaluated_object(depsgraph, object); + BKE_vfont_to_curve_nubase(evaluated_object, FO_EDIT, &new_curve->nurb); + + new_curve->type = OB_CURVE; + + new_curve->flag &= ~CU_3D; + BKE_curve_curve_dimension_update(new_curve); + + return new_curve; +} + +static Curve *curve_from_curve_object(Object *object, Depsgraph *depsgraph, bool apply_modifiers) +{ + Object *evaluated_object = DEG_get_evaluated_object(depsgraph, object); + Curve *curve = (Curve *)evaluated_object->data; + Curve *new_curve = (Curve *)BKE_id_copy_ex(NULL, &curve->id, NULL, LIB_ID_COPY_LOCALIZE); + + if (apply_modifiers) { + BKE_curve_calc_modifiers_pre(depsgraph, + DEG_get_input_scene(depsgraph), + evaluated_object, + BKE_curve_nurbs_get(curve), + &new_curve->nurb, + DEG_get_mode(depsgraph) == DAG_EVAL_RENDER); + } + + return new_curve; +} + +Curve *BKE_curve_new_from_object(Object *object, Depsgraph *depsgraph, bool apply_modifiers) +{ + if (!ELEM(object->type, OB_FONT, OB_CURVE)) { + return NULL; + } + + if (object->type == OB_FONT) { + return curve_from_font_object(object, depsgraph); + } + + return curve_from_curve_object(object, depsgraph, apply_modifiers); +} diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 1fcc1b1bcef..c860e57520d 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -770,8 +770,12 @@ static ModifierData *curve_get_tessellate_point(Scene *scene, } /* Return true if any modifier was applied. */ -static bool curve_calc_modifiers_pre( - Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *nurb, const bool for_render) +bool BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph, + Scene *scene, + Object *ob, + ListBase *source_nurb, + ListBase *target_nurb, + const bool for_render) { VirtualModifierData virtualModifierData; ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData); @@ -810,13 +814,13 @@ static bool curve_calc_modifiers_pre( keyVerts = BKE_key_evaluate_object(ob, &numElems); if (keyVerts) { - BLI_assert(BKE_keyblock_curve_element_count(nurb) == numElems); + BLI_assert(BKE_keyblock_curve_element_count(source_nurb) == numElems); /* split coords from key data, the latter also includes * tilts, which is passed through in the modifier stack. * this is also the reason curves do not use a virtual * shape key modifier yet. */ - deformedVerts = BKE_curve_nurbs_key_vert_coords_alloc(nurb, keyVerts, &numVerts); + deformedVerts = BKE_curve_nurbs_key_vert_coords_alloc(source_nurb, keyVerts, &numVerts); } } @@ -832,7 +836,7 @@ static bool curve_calc_modifiers_pre( } if (!deformedVerts) { - deformedVerts = BKE_curve_nurbs_vert_coords_alloc(nurb, &numVerts); + deformedVerts = BKE_curve_nurbs_vert_coords_alloc(source_nurb, &numVerts); } mti->deformVerts(md, &mectx, NULL, deformedVerts, numVerts); @@ -845,11 +849,11 @@ static bool curve_calc_modifiers_pre( } if (deformedVerts) { - BKE_curve_nurbs_vert_coords_apply(nurb, deformedVerts, false); + BKE_curve_nurbs_vert_coords_apply(target_nurb, deformedVerts, false); MEM_freeN(deformedVerts); } if (keyVerts) { /* these are not passed through modifier stack */ - BKE_curve_nurbs_key_vert_tilts_apply(nurb, keyVerts); + BKE_curve_nurbs_key_vert_tilts_apply(target_nurb, keyVerts); } if (keyVerts) { @@ -1151,7 +1155,8 @@ void BKE_displist_make_surf(Depsgraph *depsgraph, } if (!for_orco) { - force_mesh_conversion = curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); + force_mesh_conversion = BKE_curve_calc_modifiers_pre( + depsgraph, scene, ob, &nubase, &nubase, for_render); } LISTBASE_FOREACH (Nurb *, nu, &nubase) { @@ -1501,7 +1506,8 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph, } if (!for_orco) { - force_mesh_conversion = curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); + force_mesh_conversion = BKE_curve_calc_modifiers_pre( + depsgraph, scene, ob, &nubase, &nubase, for_render); } BKE_curve_bevelList_make(ob, &nubase, for_render); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 9b5a1614dc0..04071282a52 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1742,6 +1742,7 @@ void BKE_object_free_derived_caches(Object *ob) } BKE_object_to_mesh_clear(ob); + BKE_object_to_curve_clear(ob); BKE_object_free_curve_cache(ob); /* Clear grease pencil data. */ @@ -5057,6 +5058,7 @@ void BKE_object_runtime_reset_on_copy(Object *object, const int UNUSED(flag)) runtime->mesh_deform_eval = NULL; runtime->curve_cache = NULL; runtime->object_as_temp_mesh = NULL; + runtime->object_as_temp_curve = NULL; runtime->geometry_set_eval = NULL; } @@ -5615,6 +5617,24 @@ void BKE_object_to_mesh_clear(Object *object) object->runtime.object_as_temp_mesh = NULL; } +Curve *BKE_object_to_curve(Object *object, Depsgraph *depsgraph, bool apply_modifiers) +{ + BKE_object_to_curve_clear(object); + + Curve *curve = BKE_curve_new_from_object(object, depsgraph, apply_modifiers); + object->runtime.object_as_temp_curve = curve; + return curve; +} + +void BKE_object_to_curve_clear(Object *object) +{ + if (object->runtime.object_as_temp_curve == NULL) { + return; + } + BKE_id_free(NULL, object->runtime.object_as_temp_curve); + object->runtime.object_as_temp_curve = NULL; +} + void BKE_object_check_uuids_unique_and_report(const Object *object) { BKE_pose_check_uuids_unique_and_report(object->pose); |