diff options
author | Jacques Lucke <jacques@blender.org> | 2022-05-06 15:39:36 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2022-05-06 15:39:36 +0300 |
commit | edc92f779ec1024664178e09d114e4ac85875058 (patch) | |
tree | 27664f2654a44ebb0f90738e247e93f45d2192e5 | |
parent | c7bffc8fa27b4ae2c92e018dc5f8f79e0dfff9b9 (diff) |
Curves: support converting legacy curves to new curves object
This extends the existing object type conversion operator.
Currently, it is limited to converting to curves when the evaluated
source mesh actually has curves. This might not be the case when
it is converted to a mesh by some modifier during evaluation.
Differential Revision: https://developer.blender.org/D14872
-rw-r--r-- | source/blender/editors/object/object_add.cc | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc index db8860efdd8..4b838297b7b 100644 --- a/source/blender/editors/object/object_add.cc +++ b/source/blender/editors/object/object_add.cc @@ -2762,9 +2762,32 @@ static const EnumPropertyItem convert_target_items[] = { "Point Cloud", "Point Cloud from Mesh objects"}, #endif + {OB_CURVES, "CURVES", ICON_OUTLINER_OB_CURVES, "Curves", "Curves from evaluated curve data"}, {0, nullptr, 0, nullptr, nullptr}, }; +static const EnumPropertyItem *convert_target_items_fn(bContext *UNUSED(C), + PointerRNA *UNUSED(ptr), + PropertyRNA *UNUSED(prop), + bool *r_free) +{ + EnumPropertyItem *items = nullptr; + int items_num = 0; + for (const EnumPropertyItem *item = convert_target_items; item->identifier != nullptr; item++) { + if (item->value == OB_CURVES) { + if (U.experimental.use_new_curves_type) { + RNA_enum_item_add(&items, &items_num, item); + } + } + else { + RNA_enum_item_add(&items, &items_num, item); + } + } + RNA_enum_item_end(&items, &items_num); + *r_free = true; + return items; +} + static void object_data_convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Object *ob) { if (ob->runtime.curve_cache == nullptr) { @@ -3065,6 +3088,50 @@ static int object_convert_exec(bContext *C, wmOperator *op) } ob_gpencil->actcol = actcol; } + else if (target == OB_CURVES) { + 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 (geometry.has_curves()) { + if (keep_original) { + basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, nullptr); + newob = basen->object; + + /* Decrement original curve's usage count. */ + Curve *legacy_curve = static_cast<Curve *>(newob->data); + id_us_min(&legacy_curve->id); + + /* Make a copy of the curve. */ + newob->data = BKE_id_copy(bmain, &legacy_curve->id); + } + else { + newob = ob; + } + + const CurveComponent &curve_component = *geometry.get_component_for_read<CurveComponent>(); + const Curves *curves_eval = curve_component.get_for_read(); + Curves *new_curves = static_cast<Curves *>(BKE_id_new(bmain, ID_CV, newob->id.name + 2)); + + newob->data = new_curves; + newob->type = OB_CURVES; + + blender::bke::CurvesGeometry::wrap( + new_curves->geometry) = blender::bke::CurvesGeometry::wrap(curves_eval->geometry); + BKE_object_material_from_eval_data(bmain, newob, &curves_eval->id); + + BKE_object_free_derived_caches(newob); + BKE_object_free_modifiers(newob, 0); + } + else { + BKE_reportf( + op->reports, RPT_WARNING, "Object '%s' has no evaluated curves data", ob->id.name + 2); + } + } else if (ob->type == OB_MESH && target == OB_POINTCLOUD) { ob->flag |= OB_DONE; @@ -3480,6 +3547,7 @@ void OBJECT_OT_convert(wmOperatorType *ot) /* properties */ ot->prop = RNA_def_enum( ot->srna, "target", convert_target_items, OB_MESH, "Target", "Type of object to convert to"); + RNA_def_enum_funcs(ot->prop, convert_target_items_fn); RNA_def_boolean(ot->srna, "keep_original", false, |