Object: Support converting curves object to mesh

Previously you had to use a workaround with the Object info node to get
evaluated data from the new curves object to an original editable mesh.
This commit makes it so that a curves object can be converted directly
to a mesh object if it has evaluated curves or an evaluated mesh.

Differential Revision: https://developer.blender.org/D16930
This commit is contained in:
Hans Goudey 2023-01-06 09:29:39 -05:00
parent 87fd798ae3
commit 2752a88478
Notes: blender-bot 2023-02-14 09:24:53 +01:00
Referenced by commit 6f38ce5a40, Fix T103679: Add missing operators in object context menu for point cloud and curves
2 changed files with 52 additions and 1 deletions

View File

@ -2,7 +2,6 @@
#pragma once
struct CurvesGeometry;
struct Mesh;
/** \file
@ -11,6 +10,7 @@ struct Mesh;
namespace blender::bke {
struct CurvesGeometry;
class AnonymousAttributePropagationInfo;
/**

View File

@ -49,6 +49,7 @@
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_curve_to_mesh.hh"
#include "BKE_curves.h"
#include "BKE_displist.h"
#include "BKE_duplilist.h"
@ -2877,6 +2878,7 @@ static Base *duplibase_for_convert(
static int object_convert_exec(bContext *C, wmOperator *op)
{
using namespace blender;
Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
@ -3359,6 +3361,55 @@ static int object_convert_exec(bContext *C, wmOperator *op)
ED_rigidbody_object_remove(bmain, scene, newob);
}
}
else if (ob->type == OB_CURVES && target == OB_MESH) {
ob->flag |= OB_DONE;
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
GeometrySet geometry;
if (ob_eval->runtime.geometry_set_eval != nullptr) {
geometry = *ob_eval->runtime.geometry_set_eval;
}
if (keep_original) {
basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, nullptr);
newob = basen->object;
Curves *curves = static_cast<Curves *>(newob->data);
id_us_min(&curves->id);
newob->data = BKE_id_copy(bmain, &curves->id);
}
else {
newob = ob;
}
Mesh *new_mesh = static_cast<Mesh *>(BKE_id_new(bmain, ID_ME, newob->id.name + 2));
if (const Mesh *mesh_eval = geometry.get_mesh_for_read()) {
BKE_mesh_nomain_to_mesh(BKE_mesh_copy_for_eval(mesh_eval, false), new_mesh, newob);
BKE_object_material_from_eval_data(bmain, newob, &mesh_eval->id);
new_mesh->attributes_for_write().remove_anonymous();
}
else if (const Curves *curves_eval = geometry.get_curves_for_read()) {
bke::AnonymousAttributePropagationInfo propagation_info;
propagation_info.propagate_all = false;
Mesh *mesh = bke::curve_to_wire_mesh(bke::CurvesGeometry::wrap(curves_eval->geometry),
propagation_info);
BKE_mesh_nomain_to_mesh(mesh, new_mesh, newob);
BKE_object_material_from_eval_data(bmain, newob, &curves_eval->id);
}
else {
BKE_reportf(op->reports,
RPT_WARNING,
"Object '%s' has no evaluated mesh or curves data",
ob->id.name + 2);
}
newob->data = new_mesh;
newob->type = OB_MESH;
BKE_object_free_derived_caches(newob);
BKE_object_free_modifiers(newob, 0);
}
else {
continue;
}