Curves: Implement join operator
Previously the object join operator wasn't implemented for the new curves type. This commit implements the joining by passing the selected curves geometry as instances to the realize instances function. That way the complexity of the new code just relates to dealing with objects. Pull Request: https://projects.blender.org/blender/blender/pulls/134691
This commit is contained in:
@@ -24,6 +24,7 @@ set(SRC
|
||||
intern/curves_ops.cc
|
||||
intern/curves_selection.cc
|
||||
intern/curves_undo.cc
|
||||
intern/join.cc
|
||||
intern/select_linked_pick.cc
|
||||
intern/separate.cc
|
||||
)
|
||||
|
||||
87
source/blender/editors/curves/intern/join.cc
Normal file
87
source/blender/editors/curves/intern/join.cc
Normal file
@@ -0,0 +1,87 @@
|
||||
/* SPDX-FileCopyrightText: 2025 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_instances.hh"
|
||||
#include "BKE_report.hh"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
#include "DEG_depsgraph_build.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "ED_curves.hh"
|
||||
#include "ED_object.hh"
|
||||
|
||||
#include "GEO_realize_instances.hh"
|
||||
|
||||
namespace blender::ed::curves {
|
||||
|
||||
int join_objects(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *active_object = CTX_data_active_object(C);
|
||||
BLI_assert(active_object);
|
||||
BLI_assert(active_object->type == OB_CURVES);
|
||||
Curves &active_curves = *static_cast<Curves *>(active_object->data);
|
||||
const float4x4 &world_to_active = active_object->world_to_object();
|
||||
|
||||
Vector<Object *> objects{active_object};
|
||||
bool active_object_selected = false;
|
||||
CTX_DATA_BEGIN (C, Object *, object, selected_editable_objects) {
|
||||
if (object == active_object) {
|
||||
active_object_selected = true;
|
||||
continue;
|
||||
}
|
||||
if (object->type != OB_CURVES) {
|
||||
continue;
|
||||
}
|
||||
objects.append(object);
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
if (!active_object_selected) {
|
||||
BKE_report(op->reports, RPT_WARNING, "Active object is not a selected curves object");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
bke::Instances instances;
|
||||
instances.resize(objects.size());
|
||||
MutableSpan<float4x4> transforms = instances.transforms_for_write();
|
||||
MutableSpan<int> references = instances.reference_handles_for_write();
|
||||
Map<const Curves *, int> reference_by_orig_curves;
|
||||
for (const int i : objects.index_range()) {
|
||||
transforms[i] = world_to_active * objects[i]->object_to_world();
|
||||
const Curves *orig_curves = static_cast<const Curves *>(objects[i]->data);
|
||||
references[i] = reference_by_orig_curves.lookup_or_add_cb(orig_curves, [&]() {
|
||||
auto geometry = bke::GeometrySet::from_curves(BKE_curves_copy_for_eval(orig_curves));
|
||||
return instances.add_new_reference(std::move(geometry));
|
||||
});
|
||||
}
|
||||
|
||||
bke::GeometrySet realized_geometry = geometry::realize_instances(
|
||||
bke::GeometrySet::from_instances(&instances, bke::GeometryOwnershipType::ReadOnly),
|
||||
geometry::RealizeInstancesOptions());
|
||||
|
||||
Curves *realized_curves = realized_geometry.get_curves_for_write();
|
||||
active_curves.geometry.wrap() = std::move(realized_curves->geometry.wrap());
|
||||
|
||||
for (Object *object : objects.as_span().drop_front(1)) {
|
||||
object::base_free_and_unlink(bmain, scene, object);
|
||||
}
|
||||
|
||||
DEG_relations_tag_update(bmain);
|
||||
DEG_id_tag_update(&active_object->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
} // namespace blender::ed::curves
|
||||
@@ -26,6 +26,7 @@ struct ViewContext;
|
||||
struct rcti;
|
||||
struct TransVertStore;
|
||||
struct wmKeyConfig;
|
||||
struct wmOperator;
|
||||
namespace blender::bke {
|
||||
enum class AttrDomain : int8_t;
|
||||
struct GSpanAttributeWriter;
|
||||
@@ -461,6 +462,8 @@ void resize_curves(bke::CurvesGeometry &curves,
|
||||
*/
|
||||
void reorder_curves(bke::CurvesGeometry &curves, Span<int> old_by_new_indices_map);
|
||||
|
||||
int join_objects(bContext *C, wmOperator *op);
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::ed::curves
|
||||
|
||||
@@ -4714,7 +4714,8 @@ static bool object_join_poll(bContext *C)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ELEM(ob->type, OB_MESH, OB_CURVES_LEGACY, OB_SURF, OB_ARMATURE, OB_GREASE_PENCIL)) {
|
||||
if (ELEM(ob->type, OB_MESH, OB_CURVES_LEGACY, OB_SURF, OB_ARMATURE, OB_GREASE_PENCIL, OB_CURVES))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -4751,6 +4752,9 @@ static int object_join_exec(bContext *C, wmOperator *op)
|
||||
else if (ob->type == OB_ARMATURE) {
|
||||
ret = ED_armature_join_objects_exec(C, op);
|
||||
}
|
||||
else if (ob->type == OB_CURVES) {
|
||||
ret = curves::join_objects(C, op);
|
||||
}
|
||||
else if (ob->type == OB_GREASE_PENCIL) {
|
||||
ret = ED_grease_pencil_join_objects_exec(C, op);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user