Curves: Avoid duplication of control points during evaluation

This commit avoids duplicating the deformed control point
list twice by modifying the list in the object curve cache directly.

For curves, the original control point data was duplicated into a
local listbase, deformed, used to create the "bevel list" data, and
then duplicated again for the object-level storage of deformed
control points. Text objects and surface objects had a similar
unnecessary duplication.
This commit is contained in:
Hans Goudey
2021-06-28 22:22:06 -05:00
parent a3a7e19f07
commit f8d8f28e2c

View File

@@ -1100,20 +1100,21 @@ static void evaluate_surface_object(Depsgraph *depsgraph,
Mesh **r_final)
{
BLI_assert(ob->type == OB_SURF);
ListBase nubase = {nullptr, nullptr};
const Curve *cu = (const Curve *)ob->data;
ListBase *deformed_nurbs = &ob->runtime.curve_cache->deformed_nurbs;
if (!for_render && cu->editnurb) {
BKE_nurbList_duplicate(&nubase, BKE_curve_editNurbs_get(const_cast<Curve *>(cu)));
BKE_nurbList_duplicate(deformed_nurbs, BKE_curve_editNurbs_get_for_read(cu));
}
else {
BKE_nurbList_duplicate(&nubase, &cu->nurb);
BKE_nurbList_duplicate(deformed_nurbs, &cu->nurb);
}
bool force_mesh_conversion = BKE_curve_calc_modifiers_pre(
depsgraph, scene, ob, &nubase, &nubase, for_render);
depsgraph, scene, ob, deformed_nurbs, deformed_nurbs, for_render);
LISTBASE_FOREACH (const Nurb *, nu, &nubase) {
LISTBASE_FOREACH (const Nurb *, nu, deformed_nurbs) {
if (!(for_render || nu->hide == 0) || !BKE_nurb_check_valid_uv(nu)) {
continue;
}
@@ -1174,11 +1175,8 @@ static void evaluate_surface_object(Depsgraph *depsgraph,
}
}
BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase);
curve_calc_modifiers_post(
depsgraph, scene, ob, r_dispbase, for_render, force_mesh_conversion, r_final);
BKE_nurbList_free(&nubase);
}
static void rotateBevelPiece(const Curve *cu,
@@ -1408,19 +1406,19 @@ static void evaluate_curve_type_object(Depsgraph *depsgraph,
BLI_assert(ELEM(ob->type, OB_CURVE, OB_FONT));
const Curve *cu = (const Curve *)ob->data;
ListBase nubase = {nullptr, nullptr};
ListBase *deformed_nurbs = &ob->runtime.curve_cache->deformed_nurbs;
if (ob->type == OB_FONT) {
BKE_vfont_to_curve_nubase(ob, FO_EDIT, &nubase);
BKE_vfont_to_curve_nubase(ob, FO_EDIT, deformed_nurbs);
}
else {
BKE_nurbList_duplicate(&nubase, BKE_curve_nurbs_get(const_cast<Curve *>(cu)));
BKE_nurbList_duplicate(deformed_nurbs, BKE_curve_nurbs_get_for_read(cu));
}
bool force_mesh_conversion = BKE_curve_calc_modifiers_pre(
depsgraph, scene, ob, &nubase, &nubase, for_render);
depsgraph, scene, ob, deformed_nurbs, deformed_nurbs, for_render);
BKE_curve_bevelList_make(ob, &nubase, for_render);
BKE_curve_bevelList_make(ob, deformed_nurbs, for_render);
if ((cu->flag & CU_PATH) ||
DEG_get_eval_flags_for_id(depsgraph, &ob->id) & DAG_EVAL_NEED_CURVE_PATH) {
@@ -1432,13 +1430,13 @@ static void evaluate_curve_type_object(Depsgraph *depsgraph,
/* no bevel or extrude, and no width correction? */
if (BLI_listbase_is_empty(&dlbev) && cu->width == 1.0f) {
curve_to_displist(cu, &nubase, for_render, r_dispbase);
curve_to_displist(cu, deformed_nurbs, for_render, r_dispbase);
}
else {
const float widfac = cu->width - 1.0f;
const BevList *bl = (BevList *)ob->runtime.curve_cache->bev.first;
const Nurb *nu = (Nurb *)nubase.first;
const Nurb *nu = (Nurb *)deformed_nurbs->first;
for (; bl && nu; bl = bl->next, nu = nu->next) {
float *data;
@@ -1611,15 +1609,12 @@ static void evaluate_curve_type_object(Depsgraph *depsgraph,
curve_to_filledpoly(cu, r_dispbase);
}
BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase);
curve_calc_modifiers_post(
depsgraph, scene, ob, r_dispbase, for_render, force_mesh_conversion, r_final);
if (cu->flag & CU_DEFORM_FILL && !ob->runtime.data_eval) {
curve_to_filledpoly(cu, r_dispbase);
}
BKE_nurbList_free(&nubase);
}
void BKE_displist_make_curveTypes(Depsgraph *depsgraph,